问题背景
Spring Boot 项目一般会依赖较多的包括 Spring 在内的第三方 jar 包,直接打可运行 jar 包,文件大小往往会达到100M甚至更大;
在重复部署测试或者生产环境的时候,每次都要上传包含所有依赖 jar 包的可运行 jar 文件,效率比较低;
期望目标
maven 配置,Spring Boot 项目打包时,只包含自己开发的代码,大小仅100kb,所依赖的第三方 jar 则复制到指定的目录下;
这样我们可以只需要上传一次第三方 jar,每次修改代码重新部署时,只上传仅包含我们开发代码的 jar 文件,大大提高了部署效率。
解决方法
maven 的 pom 配置如下,${} 变量根据自己的项目进行替换,第三方 jar 指定到 target/lib 目录下:
maven-compiler-plugin
${java.version}
${java.version}
UTF-8
org.apache.maven.plugins
maven-surefire-plugin
true
org.apache.maven.plugins
maven-dependency-plugin
copy-dependencies
${project.build.directory}/lib
provided
org.apache.maven.plugins
maven-jar-plugin
${project.main.class}
true
./lib/
org.springframework.boot
spring-boot-maven-plugin
repackage
nothing
nothing
我们使用maven做一些日常的工作开发的时候,无非是想利用这个工具带来的一些便利。比如依赖管理,方便我们打包和部署运行。这里几个常见的插件就是和这些工程中常用的步骤相关。
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.0.2:compile (default-compile) on project springJMS: Compilation failure: Compilation failure:
[ERROR] /home/frank/programcode/SpringJMSSample/src/main/java/huangbowen/net/jms/MessageSender.java:[6,1] error: annotations are not supported in -source 1.3
[ERROR]
[ERROR] (use -source 5 or higher to enable annotations)
[ERROR] /home/frank/programcode/SpringJMSSample/src/main/java/net/EmbedBrokerApp.java:[5,7] error: static import declarations are not supported in -source 1.3
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
从错误显示的信息我们就可以看出,这是因为编译的时候是默认用的javac 1.3版本的,太老了不支持代码里的特性。为了修改这个问题,我们需要设置编译器的版本。解决这个问题的办法也比较简单,就是直接在后面的插件部分增加如下的插件,比如如下部分,将编译器的版本设定为1.6:
org.apache.maven.plugins
maven-compiler-plugin
2.3.2
1.6
1.6
org.codehaus.mojo
exec-maven-plugin
1.2.1
java
com.yunzero.App
如果我们运行的时候需要提供一些输入的参数,也可以通过configuration的元素里添加。这样后续要执行这个程序时,我们只需要在命令行执行如下命令:mvn exec:java ,然后程序就可以运行起来了。
copy:将指定坐标对应的jar包拷贝到指定目录
unpack:将指定坐标对应的jar包解压到指定目录
3.1 copy
下述配置在打包阶段会将junit包拷贝到项目的target/alternateLocation目录下
org.apache.maven.plugins
maven-dependency-plugin
3.2.0
copy
package
copy
junit
junit
3.8.1
jar
false
${project.build.directory}/alternateLocation
————————————————
3.2 copy-dependencies
和copy命令的区别是,copy是拷贝指定坐标的jar包,而copy-dependencies则是拷贝项目依赖的所有jar包,具体用法如下
maven-dependency-plugin
install
copy-dependencies
${project.build.directory}/lib
从上面的配置里我们可以看到,插件的执行被配置到install这个阶段,当然也可以是 package 阶段
这样,当我们执行命令:mvn clean install 的时候,会发现对应的target目录里生成了对应的jar包和依赖包。
3.3 unpack
unpack命令可以将指定的jar包解压到指定的目录,需要注意的是,如果指定的触发阶段为compile,那么解压之后的内容会一起打包到当前项目中,而如果是package则不会,它只会打包自己项目内容
org.apache.maven.plugins
maven-dependency-plugin
3.2.0
unpack
compile
unpack
org.example.it
po.webresource
1.0-SNAPSHOT
jar
true
${project.build.directory}/classes
po.webresource-1.0-SNAPSHOT.jar
**/*.html,**/*.js
**/*test.html
3.4 unpack-dependencies
和unpack命令的区别是,unpack是解压指定坐标的jar包,而unpack-dependencies则是解压项目依赖的所有jar包,具体用法如下
org.apache.maven.plugins
maven-dependency-plugin
3.2.0
unpack-dependencies
package
unpack-dependencies
**/*.class
**/*.properties
${project.build.directory}/alternateLocation
false
true
4-1. maven-surefire-plugin 打包时跳过单元测试
maven-surefire-plugin
2.6
true
4-2. 如果单元测试中有输出中文,eclipse的控制台里中文可能会变成乱码输出,也可以通过这个插件解决,参考配置:
org.apache.maven.plugins
maven-surefire-plugin
2.16
once
-Dfile.encoding=UTF-8
org.apache.maven.plugins
maven-resources-plugin
2.4.3
compile
${project.build.sourceEncoding}
org.apache.maven.plugins
maven-assembly-plugin
3.1.0
assembly
package
single
html
assemblies.xml
除了需要在pom中配置上述内容外,还需要引入一个配置文件assemblies.xml(名字由自己指定)
html
zip
${project.build.directory}/classes
true
**/*.log
**/${project.build.directory}/**