2010-12-09 37 views
1

我想在運行時使用Class.forName從文件系統上的.jar文件動態加載類。我試圖加載的類在另一個.jar文件中實現了一個接口,因此我使用自己的URLClassLoader來引用這兩個.jar。Java Class.forName問題

當代碼不在Web應用程序的上下文中調用時(我已通過將該方法複製並粘貼到獨立程序並從main調用它來測試此代碼)時,該代碼有效。但是,當我運行/調試Web應用程序(我正在使用NetBeans)時,代碼失敗。當我嘗試將實例強制轉換到jar_file_dependencies.jar中指定的接口時,newInstance方法拋出ClassCastException。

下面是相關的代碼,如果這有助於:

 File gameJar = new File("C:\\file_path\\jar_file.jar"); 

     File gameDependenciesJar = new File("C:\\file_path\\jar_file_dependencies.jar"); 

     URLClassLoader cl = new URLClassLoader(new URL[] 
       { 
        gameJar.toURI().toURL(), 
        gameDependenciesJar.toURI().toURL() 
       }); 

     Class clazz = Class.forName("MyClass", true, cl); 

     IMyClass myClass = (IMyClass)clazz.newInstance(); 

     System.out.println(game); 

    } catch (Exception e) 
    { 
     System.out.println(e.getMessage()); 
    } 

任何建議,爲什麼這個代碼在一個程序中工作而不是另一個將不勝感激。

非常感謝, 丹

+1

難道是這個問題:http://stackoverflow.com/questions/2081000/java-lang-classcastexception-when-casting-object-result-of-java-lang-reflect-met? – Lars 2010-12-09 20:27:08

+1

@Lars,我認爲確實是這個問題。會建議同樣的事情 - 給URLClassLoader一個父母。 – 2010-12-09 20:31:36

回答

1

沒有進入太多的細節毛毛簡短的回答:一個或兩個gameJar和gameDependenciesJar的可能含有IMyClass類/接口的定義。在使用子類加載器時的經驗法則是子類加載器應該包含而不是包含任何「共享」類 - 它們應該只存在於父類加載器中。

部分解釋:Web應用類加載器通常具有與正常類加載器不同的委派策略。他們往往更喜歡孩子的班級到家長的班級。普通的類加載器通常更喜歡父類的子類。在您的Web應用程序中,您最終得到了2個單獨的IMyClass類定義(一個在父類加載器中,另一個在子代中)。在普通應用程序中,子類加載器中的IMyClass定義將被忽略,因此只有一個定義被加載(在父類加載器中),並且一切都很開心。

0

也許這將幫助,(未經測試)

ClassLoader clsLoader = Thread.currentThread().getContextClassLoader(); 
if (clsLoader == null) { 
    clsLoader = this.getClass().getClassLoader(); 
} 

URLClassLoader cl = new URLClassLoader(new URL[] 
       { 
        gameJar.toURI().toURL(), 
        gameDependenciesJar.toURI().toURL() 
       }, clsLoader); 

此外,你應該把類MyClass聲明名稱,而不是隻是調用它MyClassClass.forName()

E.g.

Class clazz = Class.forName("com.xxxx.yyy.MyClass", true, cl);