2012-10-01 55 views
2

幾個小時後,即使在閱讀過大量的文檔和SO問題之後,我仍然在智慧的結尾。我確定我錯過了一些明顯的東西,但我無法弄清楚。運行包含庫jar的jar時出現NoClassDefFoundError

我創建了一些java文件,其中包括帶有主要方法的單個入口點。該類還使用位於com.test.lib.MyLibraryClass.class中的一個「庫」類,位於jar文件mylib.jar中。我正在使用以下ant XML成功構建my jar文件。

<target name="jar" depends="compile"> 
     <jar destfile="${jar.dir}/${jar.name}.jar"> 
      <fileset dir="${classes.dir}" /> 
      <fileset dir="${lib.dir}" /> 
      <manifest> 
       <attribute name="Main-Class" value="${main-class}" /> 
       <attribute name="Class-Path" value="mylib.jar"/> 
      </manifest> 
     </jar> 
    </target> 

當我檢查通過執行這一目標創造了罐子,我看到它確實包含了我所有的.class文件以及mylib.jar。

當我試圖然而,運行jar,我得到以下錯誤:

Exception in thread "main" java.lang.NoClassDefFoundError: com/test/lib/MyLibraryClass 
    at com.mytest.MyMain.<init>(Unknown Source) 
    at com.mytest.MyMain.main(Unknown Source) 
Caused by: java.lang.ClassNotFoundException: com.test.lib.MyLibraryClass 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
    ... 2 more 

我需要做什麼改變嗎?我是否生成格式不正確或不完整的清單?

非常感謝!

回答

3

問題是標準類加載器找不到位於另一個JAR中的JAR中的類。 Class-Path清單變量是實際上告訴JVM將當前目錄中的mylib.jar文件添加到類路徑。

有三種解決方案:

  • mylib.jar文件的地方,它可以被發現(並相應設置清單屬性

  • 創建尤伯杯-JAR,結合類在你的主JAR和所有相關庫JAR文件合併爲一個JAR文件

  • 編寫一個時髦的類加載器,它知道如何從JAR中加載JAR並修改應用程序以實例化使用類加載器。 (不建議使用此方法...)

注意的是,前兩個方案解決了擺脫你的JAR-IN-A-JAR結構......以不同的方式的問題。

+0

@Walker在執行jar時可以使用java -cp jarfile jartoexecute它應該可以正常工作。 – gks

+1

@Stranger - 但這並不能直接解決JAR問題中的JAR。 –

+0

對不起:(誤解了 – gks

2

如果您嘗試使用java命令運行它,則不支持將jar包嵌入jar中。通過清單中的那個入口,類加載器將從您啓動類的基本文件夾中查找jar,而不是在jar中。您可以將mylib.jar放在您的基本文件夾中,並使用-cp mylib.jar選項運行java,或者使用支持使用嵌入式jar運行jar的任何工具。看看this或只是谷歌罐子裏的罐子,你會得到大量的點擊。

相關問題