2010-05-21 50 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