用 Maven 构建可执行的 jar?

我正在尝试使用 maven 为一个名为“ logmanager”的小型家庭项目生成一个可执行的 jar,如下所示:

如何使用 Maven 创建具有依赖项的可执行 JAR?

我将这里显示的代码片段添加到 pom.xml 中,并运行 mvn Assembly: Assembly。它在 logmanager/target 中生成两个 jar 文件: logmanager-0.1.0.jar 和 logmanager-0.1.0-jar-with-depencies.jar。当我双击第一个 jar 时,我得到一个错误:

Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.

当我双击 jar-with-Dependencentes.jar 时,会出现一个稍微不同的错误:

Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar

我复制并粘贴了路径和类名,并检查了 POM 中的拼写。我的主类从 Eclipse 启动配置启动 fine。谁能告诉我为什么我的 jar 文件不能运行?还有,为什么一开始有两个罐子?如果你需要更多信息,请告诉我。

以下是完整的 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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gorkwobble</groupId>
<artifactId>logmanager</artifactId>
<name>LogManager</name>
<version>0.1.0</version>
<description>Systematically renames specified log files on a scheduled basis. Designed to help manage MUSHClient logging and prevent long, continuous log files.</description>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<!-- nothing here -->
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- commons-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>


<!-- Quartz scheduler -->
<dependency>
<groupId>opensymphony</groupId>
<artifactId>quartz</artifactId>
<version>1.6.3</version>
</dependency>
<!-- Quartz 1.6.0 depends on commons collections -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
<!-- Quartz 1.6.0 depends on commons logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1</version>
</dependency>
<!-- Quartz 1.6.0 requires JTA in non J2EE environments -->
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
<scope>runtime</scope>
</dependency>


<!-- junitx test assertions -->
<dependency>
<groupId>junit-addons</groupId>
<artifactId>junit-addons</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>


<!-- junit dependency; FIXME: make this a separate POM -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.1</version>
</dependency>


</dependencies>
<dependencyManagement>
</dependencyManagement>
</project>
161342 次浏览

事实上,我认为你提到的 有个问题中给出的答案只是 错了(更新-20101106:有人修好了,这个的答案指的是 编辑前的版本) ,这至少部分解释了为什么你会遇到麻烦。


它在 logmanager/target 中生成两个 jar 文件: logmanager-0.1.0.jar 和 logmanager-0.1.0-jar-with-depencies.jar。

第一个是 jar:jarpackage阶段生成的 logmanager 模块的 JAR (因为该模块具有 jar类型的打包)。第二个是由 assembly:assembly生成的程序集,它应该包含来自当前模块及其依赖项的类(如果使用了描述符 jar-with-dependencies)。

当我双击第一个 jar 时,我得到一个错误:

Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.

如果您应用了作为参考发布的链接的建议配置,那么您配置了 jar 插件来生成一个可执行的工件,比如:

  <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
</manifest>
</archive>
</configuration>
</plugin>

所以 logmanager-0.1.0.jar的确是可执行的,但是是1。这不是你想要的(因为它没有所有的依赖关系)和2。它不包含 com.gorkwobble.logmanager.LogManager(这就是错误所说的,请检查 jar 的内容)。

当我双击 jar-with-Dependencentes.jar 时,会出现一个稍微不同的错误:

Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar

同样,如果您按照建议配置了汇编插件,那么您就会得到这样的东西:

  <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>

通过这种设置,logmanager-0.1.0-jar-with-dependencies.jar包含来自当前模块 还有的类及其依赖项,但是根据错误,它的 META-INF/MANIFEST.MF 没有包含一个 Main-Class条目(可能与 logmanager-0.1.0.jar 中的 MANIFEST.MF 不同)。Jar 实际上是 没有可执行文件,这也不是您想要的。


因此,我的建议是从 maven-jar-plugin 中删除 configuration元素,并像下面这样配置 maven-Assembly-plugin:

  <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<!-- nothing here -->
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>org.sample.App</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>

当然,用要执行的类替换 org.sample.App。小奖励,我已经绑定 assembly:singlepackage阶段,所以你不必再运行 assembly:assembly了。只要运行 mvn install,程序集就会在标准构建期间生成。

因此,请使用上面给出的配置更新 pom.xml 并运行 mvn clean install。然后,将 cd 放入 target目录,再试一次:

java -jar logmanager-0.1.0-jar-with-dependencies.jar

如果您得到一个错误,请更新您的问题与它,并张贴的内容的 META-INF/MANIFEST.MF文件和相关的部分,您的 pom.xml(插件配置部分)。此外,请张贴以下结果:

java -cp logmanager-0.1.0-jar-with-dependencies.jar com.gorkwobble.logmanager.LogManager

证明它在命令行上正常工作(不管 eclipse 说什么)。

编辑: 对于 Java 6,您需要配置 maven 编译器插件:

  <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>

如果您不想在包上执行装配目标,可以使用下面的命令:

mvn package assembly:single

这里 包裹是关键字。

帕斯卡 · 蒂文特的答案也帮助了我。 但是 如果你在 <pluginManagement>元素中管理你的插件,你必须在插件管理之外重新定义组装,否则如果你运行 mvn install,依赖项就不会打包在 jar 中。

<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>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>




<build>
<pluginManagement>
<plugins>


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>main.App</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>


</plugins>


</pluginManagement>


<plugins> <!-- did NOT work without this  -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
</plugins>


</build>




<dependencies>
<!--  dependencies commented out to shorten example -->
</dependencies>


</project>

右键单击该项目并给出 maven build、 maven clean、 maven generatedresource 和 maven install。