7

I have a simple jar file containing class A:

public class A {}

Then I load it in runtime:

var classLoader = new URLClassLoader(Array(my_jar_file.toURI.toURL))
var clazz = classLoader.loadClass("A")

It is ok, it can load the class A. This command is also ok:

clazz.newInstance

But when I cast it to A:

clazz.newInstance.asInstanceOf[A]

I got this error:

java.lang.ClassCastException: A cannot be cast to A

Could you please help me?

Didier Dupont
  • 29,398
  • 7
  • 71
  • 90

2 Answers2

5

Your code implies that you have "A" available in one classLoader context where you are calling clazz.newInstance.asInstanceOf[A] which is a separate context from where you are getting the clazz object. The problem is that you have two different instances of the class "A" in two different classLoader contexts. An object that is created from one version of class "A" cannot be cast to an instance of the other version in a different classLoader context.

Neil Essy
  • 3,607
  • 1
  • 19
  • 23
  • Thank you. But if I do that in Java, it's fine. Could you please fix my code so I can load a class and use it? –  Jan 15 '12 at 08:53
  • I'm sorry. Actually in Java I have an interface `I`. `A` is implemented from `I`. When I load `A` from jar, I check if it is instance of `I`, then cast to `I` and use. It is ok. –  Jan 15 '12 at 09:09
  • 1
    @HiBlack - in Scala, trait with no method implementations or vals/vars compiles straight to java interface. Maybe you can make your "A" extend some trait "I", and make your cast then? – Rogach Jan 15 '12 at 09:28
  • Thanks Neil, I already got problem with `trait` as you said, after that I post this question :-( (http://stackoverflow.com/questions/8867766/scala-dynamic-object-loading) –  Jan 15 '12 at 09:41
  • @Rogach: I'm sorry, I meant you, my typo. –  Jan 15 '12 at 09:51
  • @Neil: You're absolutely right. I need to call as: `var classLoader = new URLClassLoader(Array(my_jar_file.toURI.toURL), this.getClass.getClassLoader)`, then everything is ok. Thank you so much :-) . (In Java, I don't need to specify parent). –  Jan 15 '12 at 16:01
4

I experienced a very similar problem, in that I observed a ClassCastException when casting a dynamically loaded object to an interface implemented by it.
Thanks to Neil's answer, I was able to determine that the ClassCastException was caused by having different class loader contexts.

To fix this I used the URLClassLoader(URL[] urls, ClassLoader parent) constructor instead of the URLClassLoader(URL[] urls) constructor.

Andy Hayden
  • 359,921
  • 101
  • 625
  • 535