2017-01-04 62 views
0

我的項目結構如下(非常簡化當然): project structure從具有依賴性罐子裝入另一個罐子一類

所以lib-ext下我下載每天從詹金斯服務器2的jar文件「 jar1和jar2'來檢查我的程序,我需要'jar1'中的一個文件讓我們調用它:「Class2Bloaded」。 問題是這個文件實現了一個在'jar2'中找到的接口,讓我們稱之爲'Dependency'

我想要做的是,從我的類下src「ClassThatLoads.java」,加載「Class2Bloaded.class」並告訴類加載器尋找到「jar2」來搜索實現接口「Dependency.class」

到目前爲止我的代碼(省略了異常處理):

//Create the URL pointing to Jar1 
    private URL getJarUrl(JarFile jarFile) 
    { 
     return new File(jarFile.getName()).toURI().toURL(); 
    } 

    URL jar1Url = getJarUrl(jar1); 
    ClassLoader jar1classLoader = new URLClassLoader(new URL[] { jar1Url }); 
    Class<?> Class2Bloaded = Class.forName(fullClassName, false, jar1classLoader); 

所以問題發生在Class.forName調用中,因爲我想加載的類實現了一個接口在罐子2

Exception in thread "main" java.lang.NoClassDefFoundError: com/packagewithinJar2/Dependency 

所以最終我已經準備了另一個類加載器指向「jar2」,我甚至已經得到了實際的接口,我需要:

URL jar2Url = getJarUrl(jar2); 
    ClassLoader jar2classLoader = new URLClassLoader(new URL[] { jar2Url }); 
    Class<?> Interface2Bloaded = Class.forName(fullClassName, false, jar2classLoader); 

其中「fullClassName」在第二種情況是「Class2Bloaded」所依賴的接口的完全限定名稱。 只是我不能找到任何東西在ClassLoader javadoc允許我'注入'一個額外的類加載器的依賴關係。 我希望我的解釋清楚。

+1

這些問題是爲什麼我喜歡maven – KjetilNordin

+0

爲什麼不把兩個類放在類路徑上,然後加載默認的ClassLoader來加載'Class2Bloaded'? – hotzst

+1

一個'URLClassLoader'可以加載任意數量的JARS ....不只是1 –

回答

1

做將jar2添加到罐子列表中選擇您的URLClassLoader讀的第一件事:

ClassLoader jarclassLoader = new URLClassLoader(new URL[] { jar1Url, jar2Url }); 

但正常的事情是添加jar1和jar2在classpath從此開始。

爲此,您可以使用java可執行文件的-cp參數。

例如,如果您編譯的類到bin目錄:

java -cp libext/jar1.jar:libext/jar2.jar:bin ClassThatLoads

這樣的話,你可以使用無縫的類在自己的Java源代碼,並擺脫了繁瑣的裝載部分:

public class ClassThatLoads { 
    public static void main(String[] args) { 
    Class2Bloaded stuff = new Class2Bloaded(); 
    //use stuff from here... 
    } 
} 
+0

謝謝,第一個解決方案是最合適的現在,正如我在陀螺儀Gearless的問題評論中提到的那樣 – JBoy