Skip to content

java maven 项目可执行jar包生成的6种方法示例项目, java executable jar make demo

Notifications You must be signed in to change notification settings

tekinvip/java-maven-executable-jar

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

全网最全的 java maven项目创建可执行jar的6种方法,可以用于任何JAVA项目包含spring, springboot项目

JAVA项目创建可运行的jar文件其实就是在jar文件中构建清单文件META-INF/MANIFEST.MF, 在这个前端文件中需要指定入口类 main-class, 还有打包相关的依赖项目等. 第6种方法依赖的额外包最少,文件也最小, 第五种方法生成的jar文件最大, 但是他启动的是一个tomcat服务,通常用于web项目的部署. 其他几种方法没有内置服务,适合于控制台应用的jar打包, Spring Boot Maven Plugin这个和springboot是无缝集成的,常用于springboot项目, 以下是对各种插件生成可执行jar的配置方法和各自的优缺点的总结和对比.

1. 使用maven-jar-plugin和maven-dependency-plugin插件

优点: 处理过程透明,我们可以自定义每个步骤 不足: 手动; 依赖项不在最终的jar中,这意味着只有当libs文件夹对jar是可访问和可见的时,我们的可执行jar才会运行

  • pom依赖如下
<?xml version="1.0" encoding="UTF-8"?>
<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>cn.tekin</groupId>
    <artifactId>spring_demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>5.3.29</spring.version>
    </properties>
    <dependencies>
        <!-- https://mavenlibs.com/maven/dependency/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- https://mavenlibs.com/maven/dependency/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>${project.name}</finalName>
        <plugins>
            <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>
                            <!-- 指定所有依赖的jar包的输出路径 -->
                            <outputDirectory>
                                ${project.build.directory}/libs
                            </outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>libs/</classpathPrefix>
                            <!-- 这里写入你的可执行Class的Reference 即包含main入口类的Reference -->
                            <mainClass>cn.tekin.MyApp</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>
  • 构建jar命令 这里构建的jar文件是不包含依赖文件的, 所有的依赖文件全部位于libs目录下
mvn package
  • jar包中的清单文件 META-INF/MANIFEST.MF 生成的MANIFEST.MF内容如下
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: Tekin
Class-Path: libs/spring-core-5.3.29.jar libs/spring-jcl-5.3.29.jar lib
 s/spring-context-5.3.29.jar libs/spring-aop-5.3.29.jar libs/spring-be
 ans-5.3.29.jar libs/spring-expression-5.3.29.jar
Created-By: Apache Maven 3.6.3
Build-Jdk: 1.8.0_362
Main-Class: cn.tekin.MyApp
  • 执行jar java -jar target/spring_demo.jar

2. 使用Apache Maven Assembly Plugin插件

优点: 依赖包含在jar文件中 不足: 只能对制品进行基础控制, 如没有类重定位的支持

这个配置默认会生成2个jar文件, 一个包含配置清单和依赖的jar包 xxx-jar-with-dependencies.jar, 另外一个是不包含依赖且没有清单的jar包.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <archive>
                <manifest>
                    <mainClass>
                        cn.tekin.MyApp
                    </mainClass>
                </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </execution>
    </executions>
</plugin>

注意这里省略的其他配置,其他配置见1;

  • 生成jar文件 mvn package

  • 清单文件

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: Tekin
Build-Jdk: 1.8.0_362
Main-Class: cn.tekin.MyApp
  • 运行: 这里生成的可执行jar是包含依赖包的jar文件. java -jar target/spring_demo-jar-with-dependencies.jar

3. Apache Maven Shade Plugin

优点: 依赖包含在jar文件中, 可对我们的jar制品进行高级控制, 可对依赖的类进行重命名和重新定位. 不足: 我们想使用高级功能时配置较为复杂, 生成的jar文件大小比上面2种稍大.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <shadedArtifactAttached>true</shadedArtifactAttached>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>cn.tekin.MyApp</mainClass>
                </transformer>
            </transformers>
        </configuration>
        </execution>
    </executions>
</plugin>
  • 清单文件
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: Tekin
Created-By: Apache Maven 3.6.3
Build-Jdk: 1.8.0_362
Main-Class: cn.tekin.MyApp

4. Spring Boot Maven Plugin

优点: 依赖项包含在jar文件中,我们可以在每个可访问的位置运行它,可对打包制品进行高级控制,排除jar文件的依赖项等,还可以打包war文件

不足: 添加可能不必要的Spring和Spring Boot相关类, 生成的jar文件大小比方法3稍大

 <build>
        <finalName>${project.name}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!-- 注意这里如果项目是1.8需要指定对应的版本号 否则默认会自动依赖最新版本 从而导致版本不一致而编译失败 -->
                <version>2.3.12.RELEASE</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                        <configuration>
                            <classifier>spring-boot</classifier>
                            <mainClass>
                                cn.tekin.MyApp
                            </mainClass>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>
  • 清单文件
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Archiver-Version: Plexus Archiver
Built-By: Tekin
Start-Class: cn.tekin.MyApp
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.3.12.RELEASE
Created-By: Apache Maven 3.6.3
Build-Jdk: 1.8.0_362
Main-Class: org.springframework.boot.loader.JarLauncher

5. Web Application With Executable Tomcat

优点: 依赖项包含在jar文件中,容易部署和运行

不足: 很多年未发行新版本, 且因为在内置的war文件中打包了一个内置的tomcat发行包, 所以jar文件比较大.

 	<dependencies>
 	<!-- 其他依赖..... -->

 	<!-- servlet-api依赖 -->
	  <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>

	<build>
        <finalName>${project.name}</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <executions>
                    <execution>
                        <id>tomcat-run</id>
                        <goals>
                            <goal>exec-war-only</goal>
                        </goals>
                        <phase>package</phase>
                        <configuration>
                            <path>/</path>
                            <enableNaming>false</enableNaming>
                            <finalName>webapp.jar</finalName>
                            <charset>utf-8</charset>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>
  • 清单文件
Manifest-Version: 1.0
Main-Class: org.apache.tomcat.maven.runner.Tomcat7RunnerCli

6. One Jar Maven Plugin

优点: 干净的委托模型,允许类处于OneJar的顶级,支持外部Jar,并且可以支持Native库, 在jar文件中包含了one-jar的源码,可以自己扩展 不足: 停止维护很多年了.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         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>cn.tekin</groupId>
    <artifactId>spring_demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>5.3.29</spring.version>
    </properties>

    <dependencies>
        <!-- https://mavenlibs.com/maven/dependency/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- https://mavenlibs.com/maven/dependency/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>


    </dependencies>

    <build>
        <finalName>${project.name}</finalName>
        <plugins>

            <plugin>
                <groupId>com.jolira</groupId>
                <artifactId>onejar-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <configuration>
                            <mainClass>cn.tekin.MyApp</mainClass>
                            <attachToBuild>true</attachToBuild>
                            <classifier>Tekin</classifier>
                            <!--注意 在JDK1.8中, 使用filename 这个属性会导致 Unexpected end of ZLIB input stream异常-->
                        </configuration>
                        <goals>
                            <goal>one-jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

</project>
  • 清单文件
Manifest-Version: 1.0
ImplementationVersion: 1.0-SNAPSHOT
Main-Class: com.simontuffs.onejar.Boot
One-Jar-Main-Class: cn.tekin.MyApp

总结

创建可运行的jar文件其实就是在jar文件中构建清单文件META-INF/MANIFEST.MF, 在这个前端文件中需要指定入口类 main-class, 还有打包相关的依赖项目等. 第6种方法依赖的额外包最少,文件也最小, 第五种方法生成的jar文件最大.

同一项目不同的插件生成的jar可执行文件文件大小比较:

  1. maven-jar-plugin 4.2M + 5kb
  2. Apache Maven Assembly Plugin 4.1M
  3. Apache Maven Shade Plugin 4.2M
  4. Spring Boot Maven Plugin 4.3M
  5. Web Application With Executable Tomcat 9.2M
  6. One Jar Maven Plugin 3.8M

About

java maven 项目可执行jar包生成的6种方法示例项目, java executable jar make demo

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 100.0%