使用maven打包可执行jar包

Jul 16, 2017 • KAEL


前言

在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包即可运行。