Maven打包常见问题
1. Maven 打包时,无法将scope为system的jar文件打包进war和jar中。
分析问题:
-
-
通过对maven打包的生命周期进行分析,在package阶段未将scope为system的jar打包到war或者jar中。
maven打包生命周期,通过执行mvn clean package -Dmaven.test.skip=ture -X 打印Debug信息,可知生命周期为
clean -> validate -> compile -> test -> package -> verify -> install -> deploy
[DEBUG] Lifecycle default -> [validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-te st-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration -test, verify, install, deploy] [DEBUG] Lifecycle clean -> [pre-clean, clean, post-clean] [DEBUG] Lifecycle site -> [pre-site, site, post-site, site-deploy] [DEBUG] Lifecycle default -> [validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-te st-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration -test, verify, install, deploy]也可以从IDEA中Maven中Lifecycle中显示的顺序得知

-
-
- 查看pom.xml中执行package命令的plugin插件。对如下pom.xml文件进行分析
- maven-compiler-plugin: maven compile插件 ,compile阶段使用。
- spring-boot-maven-plugin:Spring Boot的maven插件,使spring boot工程能够以maven的方式运行。提供了一下命令:
-
spring-boot:repackage: 默认是goal,在mvn package打包之后,重新打包现有的 JAR 和 WAR 档案,以便它们可以执行
从命令行使用 java -jar。参考spring boot maven plugin 官方说明Repackage existing JAR and WAR archives so that they can be executed from the command line using java -jar. With layout=NONE can also be used simply to package a JAR with nested dependencies (and no main class, so not executable).
-
spring-boot:run: 运行spring boot工程
-
spring-boot:start: 在mvn integration-test阶段,进行Spring Boot应用生命周期的管理
-
spring-boot:stop: 在mvn integration-test阶段,进行Spring Boot应用生命周期的管理
-
spring-boot:build-info: 生成使用的构建信息文件build-info.properties
-
- 查看pom.xml中执行package命令的plugin插件。对如下pom.xml文件进行分析
<build>
<plugins>
<plugin>
<!-- maven 编译插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<!-- SpringBoot 的maven 编译插件 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>org.xxx.scheduledemo.ScheduleDemoApplication</mainClass>
<layout>WAR</layout>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
-
- 分析spring-boot-maven-plugin插件,查看插件官网信息,可知
- spring-boot:repackage命令在package阶段打包时,默认只会对scope为compile+runtime的依赖进行打包。
- 默认打包时不包括scope为system的依赖。可通过修改默认属性值解决:includeSystemScope 为 true。


- 分析spring-boot-maven-plugin插件,查看插件官网信息,可知
解决方法: 使用spring-boot-maven-plugin插件,设置includeSystemScope为true即可。
2. 使用maven-war-plugin插件之后,spring-boot-maven-plugin插件的includeSystemScope不生效,无法将scope为system的依赖打包进war或者jar。
如下pom.xml文件
<build>
<plugins>
<plugin>
<groupId>com.rimerosolutions.maven.plugins</groupId>
<artifactId>wrapper-maven-plugin</artifactId>
<version>0.0.5</version>
<configuration>
<verifyDownload>true</verifyDownload>
<checksumAlgorithm>MD5</checksumAlgorithm>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
<configuration>
<mainClass>${mainClassName}</mainClass>
<addResources>true</addResources>
<executable>${isExecutable}</executable>
<layout>WAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warName>cas</warName>
<failOnMissingWebXml>false</failOnMissingWebXml>
<recompressZippedFiles>false</recompressZippedFiles>
<archive>
<compress>false</compress>
<manifestFile>${manifestFileToUse}</manifestFile>
</archive>
<overlays>
<overlay>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-webapp${app.server}</artifactId>
<excludes>
<exclude>**/hibernate-validator-5.4.1.Final.jar</exclude>
<exclude>**/validation-api-1.1.0.Final.jar</exclude>
<exclude>**/el-api-2.2.jar</exclude>
</excludes>
</overlay>
</overlays>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
</plugin>
</plugins>
<finalName>cas</finalName>
</build>
分析问题:
-
-
分析上面使用的plugin插件,可以知道在package阶段执行的插件为maven-war-plugin、spring-boot-maven-plugin.猜测:执行顺序为maven-war-plugin -> spring-boot-maven-plugin. 实际是maven-war-plugin先将工程打包成war文件,然后在通过spring-boot-maven-plugin插件,使war文件可以通过命令行java -jar xxxx.war的形式运行。
- wrapper-maven-plugin:Wrapper是一个maven插件,用于封装提供maven项目构建时所需的一切;使用maven wrapper就可以很好的确保所有参与项目者使用相同的maven版本,同时还不会影响其它项目
- spring-boot-maven-plugin:Spring Boot的maven插件,使spring boot工程能够以maven的方式运行。提供了一下命令
- maven-war-plugin:收集web应用程序的依赖,class和resource文件,并将其打包成war。在package阶段运行。
- maven-compiler-plugin: maven compile插件 ,compile阶段使用。
-
验证maven-war-plugin -> spring-boot-maven-plugin的执行顺序,确保猜测是正确。

-
查看maven-war-plugin插件的打war时的scope范围为compile+runtime.
原因显而易见: maven-war-plugin打包成war时,未将scope为system的依赖打包至其中。

-
解决办法:
maven-war-plugin插件中不存在类似于spring-boot-maven-plugin插件中includeSystemScope的属性,但可通过添加webResources属性将需要jar打包到war中。添加如下配置:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warName>cas</warName>
<failOnMissingWebXml>false</failOnMissingWebXml>
<recompressZippedFiles>false</recompressZippedFiles>
<archive>
<compress>false</compress>
<manifestFile>${manifestFileToUse}</manifestFile>
</archive>
<overlays>
<overlay>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-webapp${app.server}</artifactId>
<excludes>
<exclude>**/hibernate-validator-5.4.1.Final.jar</exclude>
<exclude>**/validation-api-1.1.0.Final.jar</exclude>
<exclude>**/el-api-2.2.jar</exclude>
</excludes>
</overlay>
</overlays>
<!-- 将指定文件夹中jar打包时添加到WEB-INF/lib/的目录 -->
<webResources>
<resource>
<directory>/src/main/resources/lib</directory>
<targetPath>WEB-INF/lib/</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
本文探讨了Maven在打包时遇到的两个问题:一是scope为system的jar无法被包含在war和jar中,二是使用maven-war-plugin后,即使设置了spring-boot-maven-plugin的includeSystemScope为true,问题仍然存在。解决方案分别是在spring-boot-maven-plugin中设置includeSystemScope为true,以及在maven-war-plugin中通过webResources配置将所需jar打包进war。
2168

被折叠的 条评论
为什么被折叠?



