Search code examples
javaclassloader

using classloader for isolating two static classes


i want to instantiate two TCP server applications within the same main method. Those server classes use lots of static and thread local fields. Is there a chance to load classes like in a different application domain?

this is my test case:

Tester class has simple getter and setter methods for setting global static object.

public class Tester {

  public Tester() {
    System.out.println(getClass().getClassLoader());
  }

  public void setText(String text) {
    GlobalObject.globalText = text;
  }

  public String getText() {
    return GlobalObject.globalText;
  }
}

This is global object that is accessible from every where. I want to limit access to this object.

public class GlobalObject {

  public static String globalText;
}

This is my test program.

public class Main {
  public static void main(String[] args) {
    // Default class loader;
    Tester ta1 = new Tester();
    ta1.setText("test");
    System.out.println(ta1.getText());

    Tester ta2 = new Tester();
    System.out.println(ta2.getText());

    // Custom class loader;
    CustomClassLoader ccl  = new CustomClassLoader();

    try {
      Tester tb = (Tester) ccl.loadClass("Tester").newInstance();
      System.out.println(tb.getText());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

The ouput is:

sun.misc.Launcher$AppClassLoader@11b86e7
test
sun.misc.Launcher$AppClassLoader@11b86e7
test
sun.misc.Launcher$AppClassLoader@11b86e7
test

The output that i want:

sun.misc.Launcher$AppClassLoader@11b86e7
test
sun.misc.Launcher$AppClassLoader@11b86e7
test
sun.misc.Launcher$AppClassLoader@1234567
null

Solution

  • You don't tell us what CustomClassLoader is.

    But in general, the default behaviour of class loaders is to delegate to their parent, so by default all class loaders eventually delegate to the actual system class loader.

    Try creating a class loader without a parent. This is how it would look like with a standard classloader:

    URL[] urls = new URL[] {new File("build/classes/").toURL()};
    ClassLoader loader = new URLClassLoader(urls, null);
    

    The second constructor parameter is the parent.