前言
在java开发的过程中,我们经常会需要打包一个可执行的jar包,同时,开发的过程也会希望能够使用maven来管理依赖,因此,将maven工程打包成一个可执行的jar包就成了一个常见的需求。
打包成单独的jar包
如果依赖的包不多,并且希望只打包成一个单独的jar包,可以使用如下配置:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<!--这里要替换成jar包main方法所在类 -->
<mainClass>${MainClass}</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- 指定在打包节点执行jar包合并操作 -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
这样配置完成之后,使用:
mvn package
在target/
目录下会多出来一个以-jar-with-dependencies
结尾的jar包,这个jar包会包含所有的依赖。
打包成特定的目录结构
使用maven打包成可执行jar包需要两个插件:
- maven-jar-plugin
- maven-assembly-plugin
maven-jar-plugin的作用是将我们的代码打成jar包并指定main函数,maven-assembly-plugin的作用是将依赖的第三方包和配置文件按照指定的目录结构存放。
将如下这段插件配置添加到pom.xml
中:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<!-- The configuration of the plugin -->
<configuration>
<!-- Configuration of the archiver -->
<archive>
<!--生成的jar中,不要包含pom.xml和pom.properties这两个文件-->
<addMavenDescriptor>false</addMavenDescriptor>
<!-- Manifest specific configuration -->
<manifest>
<!--是否要把第三方jar放到manifest的classpath中-->
<addClasspath>true</addClasspath>
<!--生成的manifest中classpath的前缀,因为要把第三方jar放到lib目录下,所以classpath的前缀是lib/-->
<classpathPrefix>lib/</classpathPrefix>
<!--应用的main class-->
<mainClass>${mainClass}</mainClass>
</manifest>
</archive>
<!--过滤掉不希望包含在jar中的文件
<excludes>
<exclude>${project.basedir}/xml/*</exclude>
</excludes>
-->
</configuration>
</plugin>
<!-- The configuration of maven-assembly-plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<!-- The configuration of the plugin -->
<configuration>
<!-- Specifies the configuration file of the assembly plugin -->
<descriptors>
<descriptor>${package.xml.path}</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
这里有两个变量:
- mainClass: 指启动的main函数。
- package.xml.path: 指打包描述文件的路径。
assembly插件需要通过一个xml来描述如何打包各种资源文件,因此需要指定打包描述文件,如src/main/assembly/package.xml
在工程的src/main/assembly
目录下(没有就手动创建)添加package.xml
,内容如下:
<assembly>
<id>bin</id>
<!-- 最终打包成一个用于发布的zip文件 -->
<formats>
<format>zip</format>
</formats>
<!-- Adds dependencies to zip package under lib directory -->
<dependencySets>
<dependencySet>
<!-- 不使用项目的artifact,第三方jar不要解压,打包进zip文件的lib目录 -->
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>lib</outputDirectory>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
<fileSets>
<!-- 把项目相关的说明文件,打包进zip文件的根目录 -->
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>README*</include>
<include>LICENSE*</include>
<include>NOTICE*</include>
</includes>
</fileSet>
<!-- 把项目的配置文件,打包进zip文件的config目录 -->
<fileSet>
<directory>${project.basedir}\src\main\config</directory>
<outputDirectory>config</outputDirectory>
<includes>
<include>*.xml</include>
<include>*.properties</include>
</includes>
</fileSet>
<!-- 把项目的脚本文件目录( src/main/scripts )中的启动脚本文件,打包进zip文件的跟目录 -->
<fileSet>
<directory>${project.build.scriptSourceDirectory}</directory>
<outputDirectory></outputDirectory>
<includes>
<include>startup.*</include>
</includes>
</fileSet>
<!-- 把项目自己编译出来的jar文件,打包进zip文件的根目录 -->
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory></outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>
这样配置完成之后,使用:
mvn package
即可打包一个zip文件,解压后双击jar包即可运行。