使用Maven创建包含依赖的可执行JAR文件
技术背景
在Java开发中,我们经常需要将项目打包成可执行的JAR文件。然而,项目往往依赖于许多第三方库,如何将这些依赖一并打包到JAR文件中,是一个常见的需求。Maven是一个强大的项目管理工具,提供了多种方式来创建包含依赖的可执行JAR文件。
实现步骤
1. 使用maven-assembly-plugin
在pom.xml
文件中添加以下配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <build> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>fully.qualified.MainClass</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> </build>
|
然后在命令行运行:
1
| mvn clean compile assembly:single
|
2. 使用maven-shade-plugin
在pom.xml
文件中添加以下配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.3</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>path.to.MainClass</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
|
然后运行:
3. 手动部署方式
复制依赖到指定目录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>prepare-package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/${project.build.finalName}.lib</outputDirectory> </configuration> </execution> </executions> </plugin>
|
使JAR文件可执行并设置类路径
1 2 3 4 5 6 7 8 9 10 11 12 13
| <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>${project.build.finalName}.lib/</classpathPrefix> <mainClass>${fully.qualified.main.class}</mainClass> </manifest> </archive> </configuration> </plugin>
|
创建可部署的归档文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <id>antrun-archive</id> <phase>package</phase> <goals> <goal>run</goal> </goals> <configuration> <target> <property name="final.name" value="${project.build.directory}/${project.build.finalName}"/> <property name="archive.includes" value="${project.build.finalName}.${project.packaging} ${project.build.finalName}.lib/*"/> <property name="tar.destfile" value="${final.name}.tar"/> <zip basedir="${project.build.directory}" destfile="${final.name}.zip" includes="${archive.includes}" /> <tar basedir="${project.build.directory}" destfile="${tar.destfile}" includes="${archive.includes}" /> <gzip src="${tar.destfile}" destfile="${tar.destfile}.gz" /> <bzip2 src="${tar.destfile}" destfile="${tar.destfile}.bz2" /> </target> </configuration> </execution> </executions> </plugin>
|
核心代码
以下是使用maven-assembly-plugin
的完整pom.xml
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <project> <build> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>fully.qualified.MainClass</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-my-jar-with-dependencies</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
|
最佳实践
- 选择合适的插件:根据项目的需求和复杂度选择合适的插件。
maven-assembly-plugin
适合简单的依赖打包,而maven-shade-plugin
更适合处理资源合并等复杂场景。 - 绑定插件到生命周期:将插件的执行绑定到Maven的生命周期阶段,如
package
阶段,这样可以在执行mvn install
或mvn package
时自动生成可执行JAR文件。 - 排除不必要的依赖:在打包时,排除不必要的依赖可以减小JAR文件的大小。可以通过设置依赖的
scope
为provided
来排除某些依赖。
常见问题
1. maven-assembly-plugin
提示“already added, skipping”
可以尝试使用其他插件,如onejar-maven-plugin
。
2. 找不到共享的装配文件
使用descriptorId
配置参数代替descriptors/descriptor
或descriptorRefs/descriptorRef
参数,并确保将共享装配文件所在的包添加到maven-assembly-plugin
的类路径中。
3. 某些依赖未被正确打包
检查依赖的scope
是否正确,确保依赖的scope
为compile
或runtime
。