Search code examples
javaclassloader

ClassLoader: Access level between two ClassLoaders and their classes


following scenario:

  • CustomClassLoaderA loads ClassA
  • CustomClassLoaderB loads ClassB

so far so good, but:

  • CustomClassLoaderA should be able to access ClassB
  • CustomClassLoaderB should be able to access ClassA

Does anyone have an idea how I can accomplish this scenario in Java? One more restriction is that the two CustomClassLoader are on the same level. Say, they have the same parent ClassLoader.

Thank you very much in advance, guys!


Solution

  • I don't think this is possible since any normal class loader implementation follows parent-first policy and they almost never look towards siblings for loading classes. I think separate class loaders are typically used to separate run time for different modules/applications so that they don't conflict in namespaces. I wouldn't want to design custom class loaders which undermine this basic idea.

    That said, I think there is a brilliant way to achieve this using interfaces and factory pattern. Let us say, ClassA implements InterfaceA and there is a factory called AFactory which creates/spits out objects of InterfaceA.

    We'll have to make sure the classes InterfaceA and AFactory are both loaded by the parent class loader.

    Then CustomClassLoaderA, registers an object of ClassA with the AFactory (probably at start-up):

    AFactory aFactory = AFactory.getInstance():
    aFactory.registerA(new ClassA());
    

    Then the code that executs in CustomClassLoaderB gets an instance of ClassA, by the following code:

    AFactory aFactory = AFactory.getInstance();
    InterfaceA a = aFactory.getA()
    a.invokeMethodInA();
    

    Similar code can be written for sharing objects of ClassB with CustomerClassLoaderA.

    Note that classes cannot be shared across incompatible class loaders, but object instances can. So, once the object is created, there should be no problem in tossing it around different class loaders, as long as there is a common interface (or LHS) to type cast it to.

    You can also use abstract classes instead of interfaces.