2009-11-25 72 views
3

我使用ant來構建我的build.xml文件,它編譯正常,但在通過「java -jar my_jar.jar」運行生成的jar時得到運行時java.lang.NoClassDefFoundError。這似乎很多,但沒有任何相關問題的解決方案爲我工作。當運行java -jar(仍未解決)時發生java.lang.ClassNotFoundException

我的類路徑javac只包含「/usr/local/lib/libthrift.jar」,主要的.java文件導入了一堆節儉包,如org.apache.thrift.transport.TTransportException

當我嘗試通過運行程序:

java -jar MyClass.jar 

,我得到的錯誤:

Exception in thread "main" **java.lang.NoClassDefFoundError**: org/apache/thrift/transport/TTransportException 
Caused by: java.lang.ClassNotFoundException: org.apache.thrift.transport.TTransportException 
     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:307) 
     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:252) 
     at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) 
Could not find the main class: **MyClass**. Program will exit. 

下面是到目前爲止我試過的東西不工作:

  • 在命令行中添加一個標誌,如「java -cp /usr/local/lib/libthrift.jar-jar my_jar.jar」,結果是同樣的錯誤如上

  • 加入<attribute name="Class-Path" value="./:/usr/local/lib/libthrift.jar"/>我罐子的manifest>標籤內,結果是同樣的錯誤如上

  • 加入-Xbootclasspath/a:/usr/local/lib/libthrift.jar:./到java命令行。它解決了第一個錯誤,但不同的錯誤出現:在線程「主要」 java.lang.NoClassDefFoundError

    例外:組織/阿帕奇/ log4j的/記錄器 在org.apache.thrift.transport.TServerSocket。 <clinit>(TServerSocket.java:36) 在MyClass.start(來源不明) 在MyClass.main(來源不明)

您的幫助表示讚賞!謝謝。

編輯:

如果我註釋掉實例缺少類的代碼,但離開進口,代碼執行罰款。

編輯:

我感動我的Java類的服務器,並在清單屬性與服務器所引用的MainClass,但沒有任何修復。

+0

剛剛在我的答案中添加了MANIFEST的Class-Path部分。我剛剛看到詹姆斯B的回答,所以如果這項工作,你可以選擇他的答案作爲官方的答案。 – VonC 2009-11-25 09:23:26

回答

8
Could not find the main class: MyClass 

的錯誤似乎實際上與你MANIFEST其中:

  • 可能沒有一個完整的類路徑Class-Path:看this HowTo

The best solution when you have a jar is to try to include the required jars into the manifest declaration.

Manifest-Version: 1.0 
Class-Path: 
customer_client.jar 
mailer_client.jar 
signon_client.jar 
  • 或可能不在'my_jar.jar'中充分定義MainClass。

this HowTo

<target name="jar" depends="compile"> 
    <delete file="hello.jar"/> 
    <delete file="MANIFEST.MF"/> 
    <manifest file="MANIFEST.MF"> 
     <attribute name="Built-By" value="${user.name}"/> 
     <attribute name="Main-Class" value="howto.Hello"/> 
    </manifest> 

     <jar destfile="hello.jar" 
      basedir="." 
      includes="**/*.class" 
      manifest="MANIFEST.MF" 
      /> 
    </target> 

<attribute name="Main-Class" value="howto.Hello"/>需要指定MainClass的完整路徑(包),而不僅僅是MainClass

如果你的主類是在默認包(unnamed package),我不知道它可以被加載引用(見本SO question
所以將你的JarRunner成一個包,並在適當的聲明它<attribute name="Main-Class" value="myPackage.JarRunner"/>元素。

+0

主類聲明爲JarRunner類,並位於與build.xml相同的目錄中的JarRunner.java中。在我的清單中,屬性如下所示: 屬性名稱=「Main-Class」value =「JarRunner」/> 這是錯誤的嗎? – 2009-11-25 08:35:44

+0

我會推薦至少有一個包放入'JarRunner',而不是「未命名包」 – VonC 2009-11-25 08:43:50

+0

如果我將我的java文件添加到包中,然後將MainClass指定爲mypackage.JarRunner,它仍然找不到該類。這是正確的嗎? – 2009-11-25 08:47:52

1

你自己給出了答案:-)將所有的jar添加到你的運行時類路徑中。正如你之前說的那樣* .jar解決了一個問題,但是記錄器無法找到,所以將log4j.jar添加到路徑中。基本上這個想法是將所有運行所需的jar添加到classpath中。

4

在執行java -jar my-test.jar之前,您需要在清單文件的類路徑中指定所需的所有其他jar,這裏是我的一個清單文件的副本。另外

Manifest-Version: 1.0 
Archiver-Version: Plexus Archiver 
Created-By: Apache Maven 
Built-By: James B 
Build-Jdk: 1.6.0_01 
Package: com.blah.dbfieldcleaner 
Specification-Title: db_field_cleaner 
Specification-Version: 2.5.7-SNAPSHOT 
Implementation-Title: db_field_cleaner 
Implementation-Version: 2.5.7-SNAPSHOT 
Implementation-Vendor-Id: com.blah.dbfieldcleaner 
Implementation-Vendor: 
Main-Class: com.blah.dbfieldcleaner.main.Main 
mode: development 
url: ..\..\db_field_cleaner\target\site 
Class-Path: log4j-1.2.14.jar cygna_commons-2.5.7-SNAPSHOT.jar mail-1.4 
.jar activation-1.1.jar jdic-0.9.5.jar jdic_native-0.9.5.jar jdic_plu 
s-0.2.2.jar jdic_plus_native-0.2.2.jar jtds-1.2.2.jar xstream-1.3.1.j 
ar xpp3_min-1.1.4c.jar commons-net-2.0.jar text_processing-2.5.7-SNAP 
SHOT.jar 

,使用Maven,它的負載更擅長這種東西:與清單所有這些條目我可以指定java -jar db_field_cleaner.jar和所有其他的罐子內聯到類路徑!

0

可以找到java的命令行選項here

-jar-cp/-classpath選項是互斥的。 -jar選項需要使用清單,並且應該在此文件中列出依賴關係的相對路徑。但實質上,清單是一個可選機制 - 您可以在引導時間在外部指定所需的信息。如果清單造成您的問題,請不要使用它。

我想測試你是否有你已經找到了所有的依賴,像這樣的命令:

java -cp /usr/local/lib/libthrift.jar:my_jar.jar MyClass 

注意,編譯器可能成功編譯你的類即使所有可能在運行時所需的類不存在。如果您的類的直接依賴關係存在,編譯將會成功。您的依賴關係的依賴關係不是創建二進制文件所必需的,編譯器也不會不必要地檢查它們。

關於org/apache/log4j/Logger的消息表明您缺少對log4j的依賴關係。將這個庫添加到類路徑中是必要的。檢查Thrift庫的文檔以確定它的依賴關係。

0

你可以嘗試加入的罐子到服務器的域。我有一個類似的問題,當我在glassfish上運行它時,這對我很有用。我會得到那些沒有發現的例外。 Eclipse識別它,它編譯得很好,但是當在服務器上運行時,它找不到該文件。嘗試將其添加到服務器安裝到的任何lib目錄中。

0

這是正在發生的問題,

如果JAR文件是從已加載「C:\ java的\ APPS \ appli.jar」,和你的清單文件具有類路徑:參考「LIB/other.jar「,類加載器將在」other.jar「中查找」C:\ java \ apps \ lib \「。它不會查看JAR文件條目「lib/other.jar」。

解決方案: -

  1. 右鍵單擊項目,選擇導出。
  2. 選擇Java文件夾並在其中選擇Runnable JAR文件而不是JAR文件。
  3. 選擇適當的選項並在庫處理部分選擇第三個選項,即(將所需的庫複製到生成的JAR旁邊的子文件夾中)。
  4. 單擊完成,您的JAR將與指定位置一起創建,其中包含清單文件中提到的JARS的文件夾。
  5. 打開終端,提供正確的路徑,你的罐子,使用此命令Java的罐子abc.jar運行

    現在會發生什麼是類加載器會在正確的文件夾以來的引用JARS現在它們出現在包含您的應用程序JAR的相同文件夾中。現在沒有引發「java.lang.NoClassDefFoundError」異常。

這對我有效......希望它也能起作用!!!

+0

那麼這個作品,但我不認爲這是你想要的。可運行jar的優點應該是它只有一個文件。您的解決方案需要其他文件 – T3rm1 2013-08-06 06:41:18

相關問題