2012-05-12 54 views
40

我第一次使用Maven和我被困在依賴關係中。對Maven的依賴關係的NoClassDefFoundError

我使用Eclipse創建了一個Maven項目並添加了依賴項,並且它沒有任何問題。

但是當我嘗試通過命令行來運行它:

$ mvn package # successfully completes 
$ java -cp target/bil138_4-0.0.1-SNAPSHOT.jar tr.edu.hacettepe.cs.b21127113.bil138_4.App # NoClassDefFoundError for dependencies 

它下載的依賴,成功建立,但是當我嘗試運行它,我得到NoClassDefFoundError的:

Exception in thread "main" java.lang.NoClassDefFoundError: org/codehaus/jackson/JsonParseException 
     at tr.edu.hacettepe.cs.b21127113.bil138_4.db.DatabaseManager.<init>(DatabaseManager.java:16) 
     at tr.edu.hacettepe.cs.b21127113.bil138_4.db.DatabaseManager.<init>(DatabaseManager.java:22) 
     at tr.edu.hacettepe.cs.b21127113.bil138_4.App.main(App.java:10) 
Caused by: java.lang.ClassNotFoundException: org.codehaus.jackson.JsonParseException 
     at java.net.URLClassLoader$1.run(URLClassLoader.java:217) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:205) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:321) 
     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:266) 
     ... 3 more 

我POM .xml是這樣的:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>tr.edu.hacettepe.cs.b21127113</groupId> 
    <artifactId>bil138_4</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <name>bil138_4</name> 
    <url>http://maven.apache.org</url> 

    <properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    </properties> 

    <dependencies>   
    <dependency> 
      <groupId>org.codehaus.jackson</groupId> 
      <artifactId>jackson-core-asl</artifactId>   
    </dependency> 
     <dependency> 
      <groupId>org.codehaus.jackson</groupId> 
      <artifactId>jackson-mapper-asl</artifactId>    
     </dependency> 
    </dependencies> 
    <dependencyManagement> 
    <dependencies> 
    <dependency> 
     <groupId>org.codehaus.jackson</groupId> 
     <artifactId>jackson-core-asl</artifactId> 
     <version>1.9.6</version> 
    </dependency> 
    <dependency> 
     <groupId>org.codehaus.jackson</groupId> 
     <artifactId>jackson-mapper-asl</artifactId> 
     <version>1.9.6</version> 
    </dependency> 
    </dependencies> 
    </dependencyManagement> 
</project> 

任何人都可以幫我嗎?

回答

16

when I try to run it, I get NoClassDefFoundError

運行它如何?您可能試圖在沒有正確導入Maven類路徑的情況下使用eclipse運行它。查看m2eclipse插件用於整合maven和eclipse。

要驗證你的Maven的配置是正確的,你可以使用該exec plugin運行你的應用程序:

mvn exec:java -D exec.mainClass=<your main class> 

更新:首先,運行exec:java當關於你的錯誤,你的主類是tr.edu.hacettepe.cs.b21127113.bil138_4.App。在談論班級名稱時,他們幾乎總是用點分隔。簡單的課程名稱只是最後一部分:App您的情況。完全限定的名稱是完整的包和簡單的類名,這就是當你想運行某些東西時你給maven或者java的東西。您嘗試使用的是源文件的文件系統路徑。這是一個完全不同的野獸。與文件系統中的源文件相比,類名通常直接轉換爲在類路徑中找到的類文件。在你的具體情況下,有問題的類文件可能會在target/classes/tr/edu/hacettepe/cs/b21127113/bil138_4/App.class,因爲maven編譯爲target/classes,而且java傳統上會爲每個級別的打包創建一個目錄。

你原來的問題只是你沒有把傑克遜的罐子放在你的課堂路徑上。當你從命令行運行一個Java程序時,你必須設置類路徑,讓它知道它可以從哪裏加載類。你已經添加了你自己的jar,但沒有添加其他必需的jar。你的評論讓我覺得你不懂如何手動建立一個班級路徑。簡而言之,類路徑可以有兩件事:包含類文件的目錄和包含類文件的jar。含有罐子的目錄不起作用。有關構建班級路徑的更多詳細信息,請參閱「Setting the class path」和javajavac工具文檔。

你的類路徑將需要至少,並且沒有換行:

target/bil138_4-0.0.1-SNAPSHOT.jar: 
/home/utdemir/.m2/repository/org/codehaus/jackson/jackson-core-asl/1.9.6/jackson-core-asl-1.9.6.jar: 
/home/utdemir/.m2/repository/org/codehaus/jackson/jackson-mapper-asl/1.9.6/jackson-mapper-asl-1.9.6.jar 

注意,在Windows上的分隔符是分號(;)。

我很抱歉沒有注意到它。問題就在你原來的帖子裏,但我錯過了。

+0

獲取此錯誤:http://pastebin.com/g2txkMY6。我可以使用m2eclipse插件在eclipse上運行它,我開發了它的應用程序。我不知道如何通過命令行來運行它。以及如何導入我的Maven類路徑? 編輯:嘗試添加-classpath /home/utdemir/.m2/repository/參數到java命令,仍然沒有運氣。 – utdemir

+1

更新了我的答案。 –

+0

謝謝。像你說的那樣設置類路徑解決了問題,將問題標記爲已解決。但我還有更多的問題: 1-爲什麼我不需要將Jackson添加到exec插件的類路徑中? 2-Exec插件需要編譯我的項目,所以我應該運行mvn編譯或打包,對不對? 3-這段代碼是我的任務,是否將庫添加到他們的類路徑中是他們的責任,或者我必須做些什麼? – utdemir

80

默認情況下,Maven不會在它構建的JAR文件中捆綁依賴關係,而當您嘗試在命令行上執行JAR文件時,您不會在類路徑中提供它們。這就是爲什麼Java VM在嘗試執行代碼時找不到庫類文件的原因。

您可以使用-cp參數手動指定類路徑上的庫,但這很快就會變得令人厭煩。

更好的解決方案是將庫代碼「遮蔽」到輸出JAR文件中。有一個叫做maven-shade-plugin的Maven插件可以做到這一點。你需要在你的POM中註冊它,當你運行mvn package時,它會自動建立一個包含你的類和你的庫代碼的類的「超級JAR」。

要簡單地捆綁所有需要的庫,以下內容添加到您的POM:

<project> 
    ... 
    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-shade-plugin</artifactId> 
     <version>1.6</version> 
     <executions> 
      <execution> 
      <phase>package</phase> 
      <goals> 
       <goal>shade</goal> 
      </goals> 
      </execution> 
     </executions> 
     </plugin> 
    </plugins> 
    </build> 
    ... 
</project> 

一旦做到這一點,你可以重新運行你上面使用的命令:

$ mvn package 
$ java -cp target/bil138_4-0.0.1-SNAPSHOT.jar tr.edu.hacettepe.cs.b21127113.bil138_4.App 

如果你想根據應包含哪些JAR,指定可執行JAR文件的Main-Class等來進一步配置陰影插件,請參閱maven-shade-plugin site上的「示例」部分。

+3

如果任何人遇到這個答案,這裏是你可以得到一個實際版本的插件,因爲1.6現在很老:http://mvnrepository.com/artifact/org.apache.maven.plugins/maven-shade -plugin – Scadge

2

你必須在pom文件中爲你的依賴做類路徑。因此您必須將所有依賴項複製到一個地方。

檢查我的博客。 http://madhawagunasekara.blogspot.com/2014/10/solving-javalangnoclassdeffounderror-in.html

<build> 
 
    <plugins> 
 
    <plugin> 
 
    <groupId>org.apache.maven.plugins</groupId> 
 
    <artifactId>maven-dependency-plugin</artifactId> 
 
    <version>2.1</version> 
 
    <executions> 
 
    <execution> 
 
     <id>copy-dependencies</id> 
 
     <phase>package</phase> 
 
     <goals> 
 
     <goal>copy-dependencies</goal> 
 
     </goals> 
 
     <configuration> 
 
     <outputdirectory>${project.build.directory}/lib</outputdirectory> 
 
     <overwritereleases>false</overwritereleases> 
 
     <overwritesnapshots>false</overwritesnapshots> 
 
     <overwriteifnewer>true</overwriteifnewer> 
 
     </configuration> 
 
    </execution> 
 
    </executions> 
 
    </plugin> 
 
    <plugin> 
 
    <groupId>org.apache.maven.plugins</groupId> 
 
    <artifactId>maven-jar-plugin</artifactId> 
 
    <version>2.4</version> 
 
    <configuration> 
 
    <archive> 
 
     <manifest> 
 
     <addClasspath>true</addClasspath> 
 
     <classpathPrefix>lib/</classpathPrefix> 
 
     <mainClass>$fullqualified path to your main Class</mainClass> 
 
     </manifest> 
 
    </archive> 
 
    </configuration> 
 
    </plugin> 
 
    
 
    </plugins> 
 
    
 
    
 
</build>

2

這是由於嗎啡罐子不是你的輸出戰/罐的一部分。 Eclipse或本地構建將它們包括爲類路徑的一部分,但遠程構建或自動/計劃構建不會將它們視爲類路徑的一部分。

您可以使用插件包含依賴jar。

添加以下代碼插入您的POM的插件部分

<plugin> 
     <artifactId>maven-assembly-plugin</artifactId> 
     <version>3.0.0</version> 
     <configuration> 
      <descriptorRefs> 
       <descriptorRef>jar-with-dependencies</descriptorRef> 
      </descriptorRefs> 
     </configuration> 
    </plugin> 
-1

對我來說,Maven的二進制文件被放置在一個安全的文件夾在我公司的筆記本電腦(Program Files文件\行家),造成的麻煩行家拉/保存的依賴庫,因此DEPS都沒有找到(NoClassDefFoundError的)

只需將行家在C:\行家

Instructions

+0

這個答案與OP的問題無關。 – shiri

+0

在我的情況下,錯誤是一樣的:NoClassDefFoundError 背後的原因:項目的Java依賴項未找到; maven無法正確創建/管理存儲庫。 我應用此解決方案後,此錯誤消失,共享上面... @shiri你怎麼能說我的答案與問題無關呢? – cepix