2010-05-21 81 views
3

失败,我已经对Java代码下面的代码片段:动态类加载运行时

final Class<?> junitCoreClass = AccessController.doPrivileged(
    new PrivilegedAction<URLClassLoader>() { 
     @Override 
     public URLClassLoader run() { 
     return new URLClassLoader(new URL[] { junitJarUrl }); 
     } 
    }).loadClass("org.junit.runner.JUnitCore"); 

System.out.println(junitCoreClass.getName()); 
final JUnitCore junitCore = (JUnitCore) junitCoreClass.newInstance(); 

编译没有问题。但是当我尝试运行它时,发生了一些奇怪的事情;一个java.lang.NoClassDefFoundError引发最后一行,指刚刚加载的类。奇怪的部分是,println打印确切的类名称。

我检查过,如果我将新实例引用保留为Object并仅通过反射操作它,一切都很好,所以违规的代码片段必须是明确的转换。

有人可以向我解释为什么会发生这种情况,还告诉我如何实现我想要做的事情?

PS:对于那些谁希望看到一个更紧密堆栈跟踪,没有太多显示:

 
java.lang.NoClassDefFoundError: org/junit/runner/JUnitCore 
    at [last line of example) 
    [lines from my app] 
Caused by: java.lang.ClassNotFoundException: org.junit.runner.JUnitCore 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:315) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:330) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:250) 
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:398) 
    at [last line of example] 
    [lines from my app] 
+0

请向我们展示异常的完整堆栈跟踪。 – 2010-05-21 23:23:19

回答

4

问题是您的主类是由类路径中没有JUnit的系统类加载器(包含-classpath的加载器)加载的。然后,您创建一个单独的类加载器,该类加载器仅在类路径中具有JUnit。当您的主类尝试转换为JUnitCore时,会要求系统类加载器加载它不包含的JUnitCore,以便发生NoClassDefFoundError。

没有方便的方法来做你想做的事情而不使用反射。您将需要(1)创建一个单独的类,以直接访问JUnitCore,(2)在URLClassLoader(目录或JAR)中包含该类的路径,(3)使用反射来加载该类,以及(4)使用反射在该类上调用一个方法。

+0

我很害怕这个: - /。感谢您精心制作的答案。 – 2010-05-22 10:29:01

-1

难道你需要或者做.loadClass("org.junit.runner.JUnitCore", **true**);否则调用resolveClass()的类在创建新实例之前的对象?

+0

我不知道你在说什么,因为Java 6在ClassLoader.loadClass()和Class.resolveClass()方法上都没有第二个参数。 – 2010-05-21 23:17:00

+0

ClassLoader.loadClass确实有第二个布尔参数,但该方法不公开。 ClassLoader.resolveClass存在。也就是说,这个问题既不相关,所以我同意downvote。 – 2010-05-22 04:42:29