使用ClassLoader后类不可用

时间:2013-07-15 21:13:40

标签: java classloader urlclassloader

如果我在运行时使用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

这似乎有效 - 1的输出为loaded com.robert.test.NumberUtil

如果我尝试使用

创建该类的实例
Class.forName("com.robert.test.NumberUtil");

我得到ClassNotFoundException: com.robert.test.NumberTest。我正在尝试做什么?或者我是否必须在1使用该类(即使用从classLoader.loadClass()返回的对象,一旦超出范围重新加载它?)。

2 个答案:

答案 0 :(得分:3)

Class.forName()不会创建您的类的新实例,它只是尝试查找该类的Class对象。 要创建新实例,可以在某个Class对象上使用newInstance():

Object something = c.newInstance(); // use proper type instead of Object!

这仅适用于使用默认构造函数实例化类;否则你必须使用反射来实例化一个对象。

另请注意,创建新的ClassLoader不会立即影响类加载行为。对于上面的示例,您必须调用

Class.forName("com.robert.test.NumberUtil", true, c); // pass explicit ClassLoader

要使ClassLoader替换当前的ClassLoader,您可能需要说

Thread.currentThread().setContextClassLoader(c)

答案 1 :(得分:0)

我解决了这个问题。我试图编译JUnit测试,然后加载生成的类,并运行用@RunWith(Suite.class)注释的任何类,但是当我尝试将类传递给JUnitCore时,加载的类似乎迷失了。

无论如何,因为这是针对自定义Ant任务的,所以我使用了Ant JUnitTask类,并使用类的规范名称来运行并将已编译的测试目录添加到JUnitTask类路径中。