如何将工程打包成可直接运行的jar?即java -jar xxx.jar能够直接运行
必备条件:
1) 主要是MANIFEST.MF指定引导类,main函数入口Main-Class
2) 如果依赖了第三包,第三包也必须打包进来
MANIFEST.MF(jar运行引导文件)文件信息:
Manifest-Version: 1.0
Built-By: kzz
Class-Path: lib/commons-lang3-3.9.jar //依赖jar位置
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_181
Main-Class: com.kai.mvn.MvnPackageTest //main函数入口
1. 利用maven-jar-plugin
配置如下:
<!--指定main.class入口-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.kai.mvn.MvnPackageTest</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!--指定依赖jar打包路径 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
缺点:这种方式的化lib不会打包到jar,把jar拷贝到其他地方执行的时候如果没有把第三方包lib目录一起拷贝那么是执行不了的,进一步优化使用maven-shade-plugin打包
2. maven-shade-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.kai.mvn.MvnPackageTest</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
缺点:这种方式会把所有依赖的jar包解压缩打包进工程jar,包括依赖jar包里面的资源文件也会一起打包,会存在同名文件覆盖的问题,比如上面的配置为了避免spring.handlers和spring.schemas发生覆盖,我们将他们配置成合并打包方式。
3. spring-boot-maven-plugin
maven-shade-plugin虽然可以把依赖的包一起打包到jar,当时还是存在覆盖的风险,特别是我们依赖spring的时候,如果没有配置合并打包规则,同名资源文件会发生覆盖,而且这些规则对于我们理解或者维护成本上也是有的。我们利用spring-boot mvn打包帮助我们简化这些过程
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.5.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
利用spring-boot-maven-plugn打包后MANIFEST.MF内容:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: zhouyanchun
Start-Class: com.kai.mvn.MvnPackageTest
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.0.5.RELEASE
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_181
Main-Class: org.springframework.boot.loader.JarLauncher //变成了springboot的启动类
启动类变成了springboot的Launcher,第三方依赖jar放在了BOOT-INF/lib/目录,jar目录的结构: