
在 Spring Boot 多模块项目中,若验收测试模块(acceptance-test)直接依赖 main-app(Spring Boot 可执行应用模块),会因 main-app 打包为 fat-jar 而导致编译失败——因其内部类路径(如 BOOT-INF/classes)不被 Maven 编译器识别,引发 “Package xxx doesn’t exist” 错误。
在 spring boot 多模块项目中,若验收测试模块(acceptance-test)直接依赖 main-app(spring boot 可执行应用模块),会因 `main-app` 打包为 fat-jar 而导致编译失败——因其内部类路径(如 `boot-inf/classes`)不被 maven 编译器识别,引发 “package xxx doesn’t exist” 错误。
根本原因在于:Spring Boot 的 spring-boot-maven-plugin 默认将 main-app 构建成可执行的 fat-jar(即包含所有依赖和特殊目录结构的重打包 JAR),其实际字节码位于 BOOT-INF/classes/ 下,而非标准 JAR 的根路径。Maven 编译器(maven-compiler-plugin)在编译 acceptance-test 模块时,仅解析 main-app 的 target/main-app-x.x.x.jar ——而该 JAR 是一个非标准归档,无法被正常解包和索引,因此无法找到 abc.xyz 等包下的类。
✅ 正确做法是分离关注点:将可执行启动逻辑与业务逻辑解耦。推荐采用以下重构结构:
parent ├── main-app-boot # Spring Boot 启动模块(仅含 Application.java + spring-boot-maven-plugin) ├── app-services # 核心业务模块(含 Service、Controller、Domain 等,无 spring-boot-maven-plugin) ├── app-dao # 数据访问模块(依赖 app-services) └── acceptance-test # 验收测试模块(仅依赖 app-services,使用 <scope>test</scope> 或 compile)
对应关键配置示例:
app-services/pom.xml(关键):
<groupId>com.example</groupId>
<artifactId>app-services</artifactId>
<packaging>jar</packaging> <!-- 不使用 spring-boot-maven-plugin -->
<!-- 仅声明常规依赖,如 spring-boot-starter -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 其他非启动相关依赖 -->
</dependencies>acceptance-test/pom.xml(修正后):
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>app-services</artifactId>
<version>${project.version}</version>
<!-- 生产代码依赖,非 test scope;因验收测试需完整业务上下文 -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>⚠️ 注意事项:
- ❌ 避免在 acceptance-test 中依赖 main-app-boot 或任何启用 repackage 的模块;
- ✅ app-services 必须声明为 packaging=jar 且不引入 spring-boot-maven-plugin,确保生成标准可引用 JAR;
- ✅ 若需在验收测试中启动完整应用上下文,可使用 @SpringBootTest(classes = {...}) 显式指定配置类,或通过 app-services 提供的 @Configuration 类构建轻量上下文;
- ? 重构后,执行 mvn clean install 将按依赖顺序自动构建 app-services → acceptance-test,编译与运行均稳定可靠。
此设计不仅解决编译问题,更符合模块化分层原则:启动器(boot)只负责装配与运行,业务逻辑(services)可被任意模块复用(包括测试、批处理、API 网关等),显著提升项目可维护性与可测性。

















