Spring Boot、Java 9 Jigsaw与Maven多模块项目:同级模块类不可访问
解决Spring Boot迁移Java 9 Jigsaw时模块间类访问问题
看起来你在把传统Spring Boot项目迁移到Java 9模块系统时遇到了模块间依赖访问的典型问题——service模块无法访问common模块的类。结合Jigsaw的规则和Spring Boot的特性,我整理了几个关键排查和解决步骤:
1. 检查common模块的module-info.java配置
Jigsaw的核心是导出包和开放包的区分,这俩是最容易踩坑的点:
- 导出需要公开访问的包:如果service模块要直接引用common里的类(比如DTO、工具类、公共服务接口),必须在common的
module-info.java里显式导出对应的包:module com.yourcompany.common { // 导出给其他模块直接访问的包 exports com.yourcompany.common.dto; exports com.yourcompany.common.utils; exports com.yourcompany.common.service; } - 开放给Spring反射访问的包:Spring大量使用反射(比如组件扫描、依赖注入、JPA实体映射),如果common里有
@Configuration、@Entity、@Component这类需要Spring反射处理的类,必须用opens关键字开放对应的包给Spring相关模块:
⚠️ 注意:module com.yourcompany.common { // 开放配置类包给Spring上下文模块 opens com.yourcompany.common.config to spring.context; // 开放实体类包给Spring核心和ORM模块 opens com.yourcompany.common.entity to spring.core, spring.orm; }opens和exports的区别是,opens只允许反射访问,exports允许直接代码引用+反射访问。
2. 检查service模块的module-info.java配置
service模块必须明确声明对common模块的依赖,否则Jigsaw会拒绝访问:
module com.yourcompany.service { // 声明依赖common模块,模块名必须和common的module-info里的名称完全一致 requires com.yourcompany.common; // 同样,根据Spring需求开放自身的包 opens com.yourcompany.service.controller to spring.web; opens com.yourcompany.service.impl to spring.context; // 依赖Spring相关模块(按需添加) requires spring.boot; requires spring.context; requires spring.web; }
⚠️ 重点:requires后面的模块名必须和common模块module-info.java里定义的模块名完全匹配,哪怕Maven的artifactId是common,模块名也可能是com.yourcompany.common,别搞混了。
3. 确保Maven插件支持Java 9模块系统
Spring Boot和Java 9的兼容性需要特定版本的Maven插件,否则编译时会忽略module-info.java或者出现依赖解析错误:
配置maven-compiler-plugin
确保使用3.8.0及以上版本,指定Java 9作为编译版本,并正确配置模块路径:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <!-- 指定编译版本为Java 9 --> <release>9</release> <!-- 让Maven识别模块路径 --> <modulePath>${project.compileClasspathElements}</modulePath> </configuration> </plugin>
配置spring-boot-maven-plugin
使用2.1.0及以上版本(该版本开始支持Java 9),如果是可执行jar,需要指定MODULE布局:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.7.15</version> <!-- 选择兼容Java 9的稳定版本 --> <configuration> <layout>MODULE</layout> <!-- 指定主类(如果需要) --> <mainClass>com.yourcompany.service.ServiceApplication</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin>
4. 验证Maven依赖配置
别忽略最基础的:service模块的pom.xml必须正确依赖common模块,确保多模块构建时依赖能被正确解析:
<dependencies> <dependency> <groupId>com.yourcompany</groupId> <artifactId>common</artifactId> <version>${project.version}</version> </dependency> <!-- 其他Spring Boot依赖 --> </dependencies>
5. 排查编译错误细节
如果上面的配置都没问题,仔细看mvn clean install输出的错误信息:
- 如果提示
package com.yourcompany.common.dto is not visible:说明common模块没导出这个包,或者service模块没requirescommon模块。 - 如果提示
module com.yourcompany.service does not read module com.yourcompany.common:说明service模块的module-info.java里没加requires com.yourcompany.common;。 - 如果提示反射访问失败:说明对应的包没
opens给Spring相关模块。
按照这些步骤排查,基本能解决模块间类无法访问的问题。
内容的提问来源于stack exchange,提问作者Samax
相关产品推荐
相关产品推荐

