You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:13:04