2011-02-24 140 views
1

這看起來應該很簡單,但我還沒有弄明白,並且沒有從閱讀文檔和搜索Web獲得太多幫助。爲了學習將Maven(2.2.1)用於多模塊項目,我使用Maven創建了一個帶有C類(包含main)和S類的簡單項目P.當我運行mvn install時,構建運行並生成建立成功的消息。但是,當我運行生成的C jar時,我得到一個異常:「線程異常」main「java.lang.NoClassDefFoundError:P/S」如何告訴Maven構建一個可執行的jar文件

目錄結構(不顯示src等子目錄)是:

P
| --C
| --S

在目錄中的pom.xml的P目前是:

<?xml version="1.0" encoding="UTF-8"?> 
<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/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>P</groupId> 
    <artifactId>P</artifactId> 
    <packaging>pom</packaging> 
    <version>1.0-SNAPSHOT</version> 
    <name>P</name> 
    <url>http://maven.apache.org</url> 

    <dependencyManagement> 
    <dependencies> 
     <dependency> 
     <groupId>P</groupId> 
     <artifactId>C</artifactId> 
     <version>${project.version}</version> 
     <scope>compile</scope> 
     </dependency> 
     <dependency> 
     <groupId>P</groupId> 
     <artifactId>S</artifactId> 
     <version>${project.version}</version> 
     <scope>compile</scope> 
     </dependency> 
     <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>3.8.1</version> 
     <scope>test</scope> 
     </dependency> 
    </dependencies> 
    </dependencyManagement> 

    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-jar-plugin</artifactId> 
     <configuration> 
      <archive> 
      <manifest> 
       <mainClass>P.C</mainClass> 
       <packageName>P.C</packageName> 
      </manifest> 
      </archive> 
     </configuration> 
     </plugin> 
    </plugins> 
    </build> 

    <modules> 
    <module>C</module> 
    <module>S</module> 
    </modules> 

</project> 

C語言中的pom.xml的是:

<?xml version="1.0" encoding="UTF-8"?> 
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <modelVersion>4.0.0</modelVersion> 
    <parent> 
    <artifactId>P</artifactId> 
    <groupId>P</groupId> 
    <version>1.0-SNAPSHOT</version> 
    </parent> 
    <groupId>P</groupId> 
    <artifactId>C</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <name>C</name> 
    <url>http://maven.apache.org</url> 
    <dependencies> 
    <dependency> 
     <groupId>P</groupId> 
     <artifactId>S</artifactId> 
     <version>${project.version}</version> 
     <scope>compile</scope> 
    </dependency> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>3.8.1</version> 
     <scope>test</scope> 
    </dependency> 
    </dependencies> 
</project> 

和S中的pom.xml的是:

<?xml version="1.0" encoding="UTF-8"?> 
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <modelVersion>4.0.0</modelVersion> 
    <parent> 
    <artifactId>P</artifactId> 
    <groupId>P</groupId> 
    <version>1.0-SNAPSHOT</version> 
    </parent> 
    <groupId>P</groupId> 
    <artifactId>S</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <name>S</name> 
    <url>http://maven.apache.org</url> 
    <dependencies> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>3.8.1</version> 
     <scope>test</scope> 
    </dependency> 
    </dependencies> 
</project> 

以上都是多次嘗試後的最新版本。

對於這個簡單的學習工作中,Java類是:

P/C/src目錄/主/ JAVA/P/C.java:

package P; 

public class C 
{ 
    public static void main(String[] args) 
    { 
     System.out.println("Hello World!"); 
     S o = new S(); 
     o.sayHey(); 
    } 
} 

和S/src目錄/主/ JAVA /P/S.java:

package P; 

public class S 
{ 
    public void sayHey() 
    { 
     System.out.println("Hey!"); 
    } 
} 

那麼,我該如何告訴Maven在C jar中包含S類呢?

回答

3

更多的研究後,我發現講的Maven的手段構建一個包含所有需要的類的jar文件。我唯一需要改變的是P目錄。首先,下面的部分必須是從構建-plugins的部分刪除

<groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-jar-plugin</artifactId> 
    <configuration> 
     <archive> 
     <manifest> 
      <mainClass>P.C</mainClass> 
      <packageName>P.C</packageName> 
     </manifest> 
     </archive> 
    </configuration> 

在它的地方,我把:

<artifactId>maven-assembly-plugin</artifactId> 
    <executions> 
     <execution> 
     <id>create-executable-jar</id> 
     <phase>package</phase> 
     <goals> 
      <goal>single</goal> 
     </goals> 
     <configuration> 
      <descriptorRefs> 
      <descriptorRef>jar-with-dependencies</descriptorRef> 
      </descriptorRefs> 
      <archive> 
      <manifest> 
       <mainClass>P.C</mainClass> 
       <packageName>P.C</packageName> 
      </manifest> 
      </archive> 
     </configuration> 
     </execution> 
    </executions> 
+1

工作得很好,謝謝。不過,我不必添加元素... –

1

該maven exec插件可能會解決您的問題。您可以使用它來運行C.jar,它將管理類路徑(並確保包含S.jar)。

添加類似這樣的東西,你的P的pom.xml:

<project> 
    ... 
    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.codehaus.mojo</groupId> 
     <artifactId>exec-maven-plugin</artifactId> 
     <version>1.1</version> 
     <executions> 
      <execution> 
      ... 
      <goals> 
       <goal>java</goal> 
      </goals> 
      </execution> 
     </executions> 
     <configuration> 
      <mainClass>P.C</mainClass> 
     </configuration> 
     </plugin> 
    </plugins> 
    </build> 
    ... 
</project> 

那麼你應該能夠像這樣運行程序:

mvn exec:java -Dexec.mainClass="P.C" 
+0

雖然我沒有讓我的聚甲醛的任何變化,我確實嘗試了你的建議命令;然而,這只是給了我更多的例外。你有沒有關於如何配置pom來完成這項工作的細節? – GreenMatt

+0

我更新了我的答案,詳細介紹瞭如何配置 – Upgradingdave

3

的Maven不被包括在構件的依賴默認:運行P你仍然需要S在你的類路徑中。

這通常不是一個問題,因爲maven本身使用傳遞依賴性:例如,如果您有另一個項目依賴於P,它會自動將P和S放入您的類路徑中。

如果你想創建一個「尤伯杯罈子:包含所有依賴一個自包含的罐子,看「蔭」插件:http://maven.apache.org/plugins/maven-shade-plugin/

+0

感謝您的回答。正如我的答案所示,我能夠使用Maven-Assembly-plugin而不是陰影。另外,謝謝你提醒我看看classpath的東西;沿着解決方案的方式,我驗證了我的代碼可以使用'java -cp C/target/classes:S/target/classes/P.C'運行。 – GreenMatt

相關問題