Reputation: 325
If I load a class from file at runtime using a URLClassLoader:
ClassLoader classLoader = new URLClassLoader(new URL[] { classesUrl }, getClass().getClassLoader());
String name = fileName.replace("\\", ".").replace("/", ".").substring(0, s.lastIndexOf("."));
System.out.println("loading class " + name);
Class c = classLoader.loadClass(name);
System.out.println("loaded " + c.getCanonicalName()); // 1
This seems to work - output at 1
is loaded com.robert.test.NumberUtil
.
If I then try to create an instance of that class using
Class.forName("com.robert.test.NumberUtil");
I get a ClassNotFoundException: com.robert.test.NumberTest
. Is what I'm trying to do possible? Or do I have to use the class at 1
(i.e. use the object returned from classLoader.loadClass()
and once it's out of scope reload it?).
Upvotes: 2
Views: 198
Reputation: 325
I worked around it. I was trying to compile JUnit tests, then load the generated classes, and run any classes annotated with @RunWith(Suite.class)
, but when I tried to pass the classes to JUnitCore, the loaded classes seemed to get lost.
Anyway, because this is for a custom Ant task anyway, I used the Ant JUnitTask class, and used the canonical names of the classes to run and added the compiled test directory to the JUnitTask classpath.
Upvotes: 0
Reputation: 5279
Class.forName()
does not create a new instance of your class, it just attempts to find the Class
object for that class.
To create a new instance, you may use newInstance() on some Class object:
Object something = c.newInstance(); // use proper type instead of Object!
This only works for instantiating classes with a default constructor; otherwise you have to use reflection to instantiate an object.
Also note that creating a new ClassLoader does not immediately affect classloading behaviour. For your example above, you had to to invoke
Class.forName("com.robert.test.NumberUtil", true, c); // pass explicit ClassLoader
To make your ClassLoader replace the current ClassLoader, you might want to say
Thread.currentThread().setContextClassLoader(c)
Upvotes: 3