admin 管理员组

文章数量: 1087652

多 module Spring

【多 module Spring-Boot 项目 repackage 问题】

某项目拆分通用工具类出来为单个 Module 时出现的问题,以下为模拟项目报错

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:testCompile (default-testCompile) on project module-b: Compilation failure[ERROR] /D:/github/multi-modules/module-b/src/test/java/com/nevertrouble/demo/moduleb/CallModuleAClassTest.java:[3,42] 程序包com.nevertrouble.demo.modulea.util不存在

引起问题的原因:拆分出来模块实际并不为 spring-boot 项目,却使用了 spring-boot-maven-plugin 进行打包,导致其他模块在编译时找不到此模块的包(idea 内部可以跳转)。

spring-boot-maven-plugin 中的 repackage 打包出来 jar 包不可被依赖。

问题项目还原

父项目 multi-modules

<?xml version="1.0" encoding="UTF-8"?>
<project><!-- SpringBoot 项目版本 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.7</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.nevertrouble.demo</groupId><artifactId>multi-modules</artifactId><version>0.0.1-SNAPSHOT</version><name>multi-modules</name><description>多模块项目</description><!-- 父项目仅作为整合入口 --><packaging>pom</packaging><!-- 模块 --><modules><module>module-a</module><module>module-b</module></modules><dependencies><!-- 子模块公共依赖 --></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

module-a 模块 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project><!-- 父项目 --><parent><groupId>com.nevertrouble.demo</groupId><artifactId>multi-modules</artifactId><version>0.0.1-SNAPSHOT</version></parent><artifactId>module-a</artifactId><name>module-a</name><dependencies><!-- module-a 自己的依赖 --></dependencies><build><plugins><!-- module-a 为工具类的模块,被依赖 --><!-- 做模块拆分的人没有更改这里,导致其他 module 在打包编译时找不到程序包 --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

module-b 的 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project><parent><groupId>com.nevertrouble.demo</groupId><artifactId>multi-modules</artifactId><version>0.0.1-SNAPSHOT</version></parent><artifactId>module-b</artifactId><name>module-b</name><dependencies><!--b 依赖 a--><dependency><groupId>com.nevertrouble.demo</groupId><artifactId>module-a</artifactId><version>0.0.1-SNAPSHOT</version></dependency></dependencies><build><plugins><!-- b 本身为 springboot 可执行程序,此处无问题 --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

当在父项目中存在 spring-boot-maven-plugin 时,子模块即便没有此插件,依旧会使用此插件进行打包,所以仅删除 module-a 中的 spring-boot-maven-plugin 是不可行的,在编译 module-a 时依旧会使用此插件。

解决方法

方法 1

同时删除 父项目 multi-modules 和 子模块 module-a 中的 spring-boot-maven-plugin 插件,则在 multi-modules 项目下进行 mvn clean package 时可以顺利打包。

这个方案有一些小瑕疵, module-a 打出来包,没有其所依赖的那些 lib,仅仅是它本身的类的编译结果。

方法 2

  • 删除父项目里的 spring-boot-maven-plugin 插件
  • 修改 module-a 中的 spring-boot-maven-plugin 插件配置,跳过 repackage
<plugins><!--跳过父项目传递过来的 spring-boot-maven-plugin 的 repackage --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals><configuration><!-- 跳过 repackage --><skip>true</skip></configuration></execution></executions></plugin>
</plugins>

这个方案同样有 方法 1 中的问题,module-a 打出来的包不包含其依赖的 lib。

module-a 打包依赖 lib

方法 1方案 2 的基础上,添加 maven-shade-plugin 插件,用于打包 module-a 的依赖 lib。

<plugins><!-- maven-shade-plugin 是为了打包其依赖的 lib --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><executions><execution><configuration><!--不生成 dependency-reduced-pom.xml--><createDependencyReducedPom>false</createDependencyReducedPom></configuration><phase>package</phase><goals><goal>shade</goal></goals></execution></executions></plugin>
</plugins>

总结

  • spring-boot-maven-plugin 中的 repackage 打包出来 jar 包不可被依赖。
  • 对非 spring-boot 的模块,如果父项目有 spring-maven-plugin,需要在此模块中跳过 repackage
  • 如果要打包非 spring-boot 的项目及其依赖包,需要使用其他插件,这里举例使用了 maven-shade-plugin
  • ps: spring-boot-maven-plugin 也依赖了 maven-shade-plugin 插件。

本文标签: 多 module Spring