如何告诉 Maven 构建可执行 jar
这看起来应该很简单,但我还没有弄清楚,也没有从阅读文档和搜索网络中得到太多帮助。为了学习在多模块项目中使用 Maven (2.2.1),我使用 Maven 创建了一个简单的项目 P,其中包含类 C(包含 main)和子类 S。当我运行 mvn install< /code> 构建运行并生成 BUILD SUCCESSFUL 消息。但是,当我运行生成的 C jar 时,出现异常:“Exception in thread "main" java.lang.NoClassDefFoundError: P/S”
目录结构(不显示 src 等子目录)为:
P
|--C
|--S
目前 P 目录下的 pom.xml 为:
<?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/main/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/main/java/P/S.java:
package P;
public class S
{
public void sayHey()
{
System.out.println("Hey!");
}
}
那么,我如何告诉 Maven将S类包含在C jar中?
This seems like it should be simple, but I've not figured it out and haven't gotten much help from reading the docs and searching the web. In an effort to learn to use Maven (2.2.1) with a multimodule project, I've used Maven to create a simple project P with a class C (containing main) and subclass S. When I run mvn install
the build runs and produces a BUILD SUCCESSFUL message. However, when I run the resulting C jar, I get an exception: "Exception in thread "main" java.lang.NoClassDefFoundError: P/S"
The directory structure (not showing the src, etc. subdirectories) is:
P
|--C
|--S
The pom.xml in directory P currently is:
<?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>
The pom.xml in C is:
<?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>
and the pom.xml in S is:
<?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>
The above are all the latest versions after several attempts.
For this simple learning exercise, the Java classes are:
P/C/src/main/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();
}
}
and S/src/main/java/P/S.java:
package P;
public class S
{
public void sayHey()
{
System.out.println("Hey!");
}
}
So, how do I tell Maven to include the S class in the C jar?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
默认情况下,Maven 不包含工件中的依赖项:要运行 P,您的类路径中仍然需要 S。
这通常不是问题,因为 Maven 本身使用传递依赖项:例如,如果您有另一个项目依赖于 P,它会自动将 P 和 S 放入您的类路径中。
如果你想创建一个“uber-jar”:一个包含所有依赖项的自包含 jar,请查看“shade”插件: http://maven.apache.org/plugins/maven-shade-plugin/
Maven does not include dependencies in artifacts by default: to run P you still need S in your classpath.
That isn't normally an issue as maven itself uses transitive dependencies: for example, if you have another project depend on P, it will automatically put both P and S in your classpath.
If you want to create a 'uber-jar': a self contained jar containing all dependencies, look at the 'shade' plugin: http://maven.apache.org/plugins/maven-shade-plugin/
经过更多研究,我找到了一种告诉 Maven 构建一个包含所有需要的类的 jar 文件的方法。我唯一需要更改的 pom 位于 P 目录中。首先,必须从构建插件部分删除以下部分:
在其位置我放置:
After more research, I've found a means of telling Maven to build a jar file which includes all the needed classes. The only pom I had to change was in the P directory. First, the following section had to be removed from the build-plugins section:
In its place I put:
maven exec 插件可能会解决您的问题。您可以使用它来运行 C.jar,它将管理类路径(并确保包含 S.jar)。
将与此类似的内容添加到您的 P pom.xml 中:
然后您应该能够像这样运行该程序:
The maven exec plugin might solve your problem. You can use it to run the C.jar and it will manage the classpath (and ensure that S.jar is included).
Add something similar to this to your P pom.xml:
Then you should be able to run the program like this: