ClassCastException because of classloaders?
Solution 1
You cannot cast between class loaders. Class identity is composed of fully qualified name and the class loader. Check class identity crysis here.
Solution 2
Yes, you are correct.
This often happens in OSGi projects, because of bad dependency management.
Solution 3
That's exactly the case. You can't use casting between classes loaded by different classloaders.
This question, "Cast across classloader" may make things clearer...
Sebastien Lorber
React expert & early adopter (January 2014) Freelance, working for Facebook/Meta as Docusaurus maintainer since 2020. Author of ThisWeekInReact.com, the best newsletter to stay up-to-date with the React ecosystem:
Updated on July 18, 2022Comments
-
Sebastien Lorber almost 2 years
While playing with classloaders i got the following exception:
Exception in thread "main" java.lang.ClassCastException: xxx.Singleton cannot be cast to xxx.Singleton
Does this mean that an instance from a classloader is not castable to an class of another classloader?
Check my code where i'm able to instanciate 3 singletons thanks to classloaders, even with the "" security.
public static void main(String[] args) throws Exception { URL basePath = new URL("file:/myMavenPath/target/classes/"); Object instance = getClassInstance(Singleton.class); System.out.println(instance); // Object instance2 = getClassInstance( new URLClassLoader( new URL[]{basePath} , null ) .loadClass("my.Singleton") ); System.out.println(instance2); // Object instance3 = getClassInstance( new URLClassLoader( new URL[]{basePath} , null ) .loadClass("my.Singleton") ); System.out.println(instance3); // Only the 1st cast is ok Singleton testCast1 = (Singleton) instance; System.out.println("1st cast ok"); Singleton testCast2 = (Singleton) instance2; System.out.println("2nd cast ok"); Singleton testCast3 = (Singleton) instance3; System.out.println("3rd cast ok"); } private static Object getClassInstance(Class clazz) throws Exception { Method method = clazz.getMethod("getInstance"); method.setAccessible(true); return method.invoke(null); } class Singleton { private static final Singleton INSTANCE = new Singleton(); public static Singleton getInstance() { return INSTANCE; } private Singleton() { Exception e = new Exception(); StackTraceElement[] stackTrace = e.getStackTrace(); if (!"<clinit>".equals(stackTrace[1].getMethodName())) { throw new IllegalStateException("You shall not instanciate the Singleton twice !",e); } } public void sayHello() { System.out.println("Hello World ! " + this); } }
-
Soumen Chandra over 7 yearsCan java run identity Crysis though?