2011-02-24 142 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

相关问题