某项目拆分通用工具类出来为单个 Module 时出现的问题,以下为模拟项目报错
1 2 3 4 5 6 7
| [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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <?xml version="1.0" encoding="UTF-8"?> <project> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.7</version> <relativePath/> </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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <?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> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
</project>
|
module-b 的 pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <?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> <dependency> <groupId>com.nevertrouble.demo</groupId> <artifactId>module-a</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies>
<build> <plugins> <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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> <configuration> <skip>true</skip> </configuration> </execution> </executions> </plugin> </plugins>
|
这个方案同样有 方法 1 中的问题,module-a 打出来的包不包含其依赖的 lib。
module-a 打包依赖 lib
在 方法 1 或 方案 2 的基础上,添加 maven-shade-plugin 插件,用于打包 module-a 的依赖 lib。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <executions> <execution> <configuration> <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 插件。