Maven 如何打包可运行jar包

时间:2022-11-11 09:37:31

目标

解决可执行jar包的打包问题;上一篇文章我们介绍了mvn package可以打包,那么如果是一个可执行的jar包,该如何打包呢?

可以执行jar

拥有函数入口(public static void main(String[] args) {}),我们可以通过java -jar xxx.jar 来执行进入这个main函数。打成可执行效果,是通过mainfest.mf文件来指定的。因此如果不依赖其他工具进行打包,需要手动添加 MANIFEST.MF 到 META-INF/MANIFEST.MF
例如:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: wangzhiping
Created-By: Apache Maven 3.1.0
Build-Jdk: 1.8.0_101
Main-Class: wzp.study.maven.mainclass.HelloWorld

maven 打包可执行jar

maven-jar-plugin

  • 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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>study.wzp.maven</groupId>
  <artifactId>maven-hello</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>maven-hello</name>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <!-- META-INF/MANIFEST.MF 添加 Main-Class: -->
              <mainClass>study.wzp.maven.App</mainClass>

              <!-- META-INF/MANIFEST.MF 添加 ClassPath: 外部依赖指定 -->
              <addClasspath>true</addClasspath>

              <!-- META-INF/MANIFEST.MF : 指定依赖包所在目录前缀 -->
              <classpathPrefix>/lib</classpathPrefix>
            </manifest>
          </archive>
        </configuration>
      </plugin>

      <!-- 自动实现将依赖拷贝到 lib 目录下,不然需要手动的执行-->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>

            <goals>
              <goal>copy-dependencies</goal>
            </goals>

            <configuration>
              <!-- ${project.build.directory} 这是项目属性,后续篇章会有讲述 -->
              <outputDirectory>${project.build.directory}/lib</outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>
  • MANIFEST.MF
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: wangzhiping
Class-Path: /lib/junit-4.10.jar /lib/hamcrest-core-1.1.jar
Created-By: Apache Maven 3.1.0
Build-Jdk: 1.8.0_101
Main-Class: study.wzp.maven.App
  • 生成的目录
    Maven 如何打包可运行jar包
    Maven 如何打包可运行jar包
使用maven-jar-plugin,存在外部依赖时,需要指定外部依赖的位置(建议使用:maven-dependency-plugin)帮助管理,不能打包在一块,感觉不是很方便。

详细参考: https://maven.apache.org/plugins/maven-jar-plugin/

maven-shade-plugin

  • 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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>study.wzp.maven</groupId>
  <artifactId>maven-hello</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>maven-hello</name>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>study.wzp.maven.App</mainClass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>
  • MANIFEST.MF
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: wangzhiping
Created-By: Apache Maven 3.1.0
Build-Jdk: 1.8.0_101
Main-Class: study.wzp.maven.App
  • 项目目录
    Maven 如何打包可运行jar包
会生成maven-hello-1.0-SNAPSHOT.jar 和 origin-maven-hello-1.0-SNAPSHOT.jar 两个打包文件,
1、maven-hello-1.0-SNAPSHOT.jar :将依赖一起合并打包的jar;
2、origin-maven-hello-1.0-SNAPSHOT.jar:不包含任何依赖的jar,如果存在依赖,那么这个文件会报错;

详细使用参考:https://maven.apache.org/plugins/maven-shade-plugin/

maven-assembly-plugin

  • pom.xml 配置
<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <mainClass>study.wzp.maven.App</mainClass>
            </manifest>
          </archive>
          <descriptorRefs>
            <descriptorRef>with-dependencies</descriptorRef>
          </descriptorRefs>

        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
</plugin>
  • 项目目录
    与shade相比,基本一致,会生成两个文件
1、maven-hello-1.0-SNAPSHOT.jar:无依赖关系,不可执行;
2、maven-hello-1.0-SNAPSHOT-jar-with-dependencies.jar:依赖合并打包,可执行。

详细可参考:https://maven.apache.org/plugins/maven-assembly-plugin/

总结

如果打包可执行jar,建议使用maven-shade-plugin或者maven-assembly-plugin,一起打包会更好些。可以直接执行。

参考:

[1] http://blog.csdn.net/xiao__gui/article/details/47341385
[2] https://baike.baidu.com/item/MANIFEST.MF