背景
之前在部署Spring Boot项目时,经常因为只修改了一小处代码、或者只更新了某个jar包,但是却需要将整个项目重新打包、上传、部署,整个包一般都会达到40-60M,每次都重复这个操作真的很耗费时间,因此就想是否能够将依赖lib与项目代码分离出来,每次部署只需要发布代码即可。
尝试
参考了一些文章并进行了试验,发现总是有这样或那样的问题。主要尝试了2种常见的方式:
1)maven-jar-plugin + maven-assembly-plugin
2)spring-boot-maven-plugin + maven-dependency-plugin + maven-resources-plugin
第1种方式,不使用spring-boot-maven-plugin插件进行打包,而是使用maven-jar-plugin打包成可执行jar包。
结果:这个方式的确可以生成llb、bin、config、xx.jar等目录结构,jar包也可以执行,
问题:但是却会提示 “Unable to resolve persistence unit root URL”,这是因为项目中引入了spring-boot-starter-data-jpa依赖。
网上说去掉该依赖就可以,但是对于这个项目却是必须使用到该依赖。
第2种方式,会在target/目录下生成lib目录,以及单独的项目jar包。程序可以正确执行。
但是目录结构比较散乱,散放在target目录中,最终还需要手动拷贝lib和jar包。不是我想要的方式,我想要将所有打包后的结果单独存在一个zip包中。
研究了下,发现使用spring-boot-maven-plugin打包出来的jar包中,包含的manifest.mf文件与使用maven-jar-plugin 打包的有些差别,
Manifest-Version: 1.0
Implementation-Title: MyTest
Implementation-Version: 0.0.2
Built-By: JinPinTech
Implementation-Vendor-Id: my.test
Spring-Boot-Version: 2.1.4.RELEASE
Main-Class: org.springframework.boot.loader.PropertiesLauncher
Start-Class: my.test.SpringBootApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_131
Implementation-URL: https://projects.spring.io/spring-boot/#/spring-boot-starter-parent/mytest
多了较多Spring-boot的配置信息,其中最主要的是Main-Class是org.springframework.boot.loader.PropertiesLauncher,而非SpringBoot的Appliction启动类。启动类放在了Start-Class。
由此想到,使用第1种方式一直报错缺少依赖,应该就是maven-jar-plugin缺少了对spring-boot-starter-data-jpa的支持。
解决
因此便想到一个新的解决方案——综合以上两种方式的优点:spring-boot-maven-plugin + maven-assembly-plugin。
1)使用spring-boot-maven-plugin,可以解决前面提到的缺少spring-boot-starter-data-jpa依赖的问题,保证jar包可以正确执行。
2)使用maven-assembly-plugin,可以非常灵活的自定义打包配置,生成干净清晰的目录结构。
经试验,果真成功,程序可以正确运行,目录结构也能自定义设置。完美!
以下就贴上我的配置方式:
- 修改pom.xml,添加插件
org.springframework.boot
spring-boot-maven-plugin
ZIP
my.test
MyTest
org.apache.maven.plugins
maven-assembly-plugin
src/main/assembly/assembly.xml
make-assembly
package
single
org.apache.maven.plugins
maven-surefire-plugin
true
- 在 src/main目录建立assembly目录,添加assembly.xml
bin
zip
false
false
lib
false
runtime
${project.basedir}
README*
LICENSE*
NOTICE*
${project.basedir}/src/main/resources
config
test
test/*
*.properties
${project.basedir}/src/main/bin
${project.build.directory}
*.jar
启动
java -Dloader.path=lib/ -jar MyTest.jar
附录
- 方式一:
org.apache.maven.plugins
maven-jar-plugin
false
true
lib/
${main.class}
org.apache.maven.plugins
maven-assembly-plugin
src/main/assembly/assembly.xml
make-assembly
package
single
- 方式二
参考了作者小红牛的《Springboot 打jar包分离lib,配置文件正确方式》的文章,以下为文章中的配置信息。
org.apache.maven.plugins
maven-compiler-plugin
1.8
org.apache.maven.plugins
maven-dependency-plugin
copy-dependencies
package
copy-dependencies
target/lib
false
false
runtime
org.springframework.boot
spring-boot-maven-plugin
ZIP
cn.jstars
datatocloud
org.apache.maven.plugins
maven-resources-plugin
UTF-8
org.apache.maven.plugins
maven-surefire-plugin
true
true
src/main/resources
static/**
templates/**
*.yml
*.properties
*.xml
*.txt