I’m trying to reference an object loaded via a classloader in a class that is loaded by another classloader. I need to do a cast-down that object to access some methods. I need a way to do this casting avoiding the other classloader.
I know that we can’t cast classes of differnt classloaders, and that is not what I need here. I need to do the casting in the same classloader avoiding the other classloader which has loaded the same class. It turned out really difficult.
Here’s a little context. As you see in the classes below, I receive an object at MyClass.configure() method via the method ComponentResolver.lookup() which is an instance of Mojo but casted to Object.
Unfortunately, Mojo mojo = clazz.cast(o) (in MyClass below) fails with a compilation error, saying the returned type of clazz.cast is Object. Can anyone tell me how to resolve this? May be via the same Class#cast method or via reflection? I’m not much familiar with reflection though!
//This is loaded by, say ClassLoader X
public class ComponentResolver {
public Object lookup(String role) {
//do something
return component; //component is an instance of Mojo interface.
}
}
Here’s MyClass that where I invoke the lookup method.
//This class including Mojo in this context is loaded by, say ClassLoader Y
public class MyClass {
public void configure() {
Object o = componentResolver.lookup("componentName");
// Mojo mojo = (Mojo) o; //causes classcastexception (obviously.)
Class<?> clazz = Class.forName("org.Mojo", false,
o.getClassLoader() );
Mojo mojo = clazz.cast(o);
//Causes compiler errors because the returned object is of type Object.
//ie incompatible types Required:Mojo, Found:Object
// Mojo mojo = (Mojo) clazz.cast(o); //again classcastexception.
mojo.execute();
}
}
The
Mojoclass loaded by your classloader and theMojoclass loaded by the other classloader are completely different classes as far as the JVM is concerned.Some options:
Mojobased on the existing one via reflection, then using that (it depends whatMojois really doing)You’re in a fundamentally nasty position, and there are no easy workarounds that I’m aware of. If you can possibly fix the classloader hierarchy, it’ll make your life a lot easier. Just having
Mojoin a classloader which both of the other classloaders have as their parent would be enough.