本质是JPMS中exports声明失效,目标模块未被识别为合法消费者;需逐层验证模块是否加载、requires拼写是否精确匹配、是否混用模块路径与类路径、exports是否覆盖正确包路径。
这个问题本质是 Java 模块系统(JPMS)中
声明失效,导致目标模块根本“收不到”导出的包——不是权限没开够,而是对方压根没被识别为合法消费者。排查需从模块依赖链的起点开始逐层验证。
确认目标模块是否在运行时被加载
Java 不会报错“找不到模块名”,而是静默跳过未解析的
。先验证目标模块是否真实存在并已加载:
运行
,看是否出现在模块列表中
若使用自定义模块路径(
),检查该路径下是否存在对应 JAR 或模块目录,且文件名/目录名与
中声明的模块名完全一致(含大小写)
启动时加参数
,观察日志中是否有
类提示
核对 requires 语句的模块名拼写与版本兼容性
必须与提供方模块的
中
声明的名称**逐字符匹配**,且不能带版本号:
错误示例:
(JPMS 不支持在 requires 中写版本)
错误示例:
但提供方实际声明为
若提供方模块使用了多版本 JAR(Multi-Release JAR),确保运行时 JDK 版本 ≥ 模块所声明的最低版本,否则模块可能被忽略
检查模块路径与类路径混用冲突
当项目同时使用
和
(或
)时,JVM 会将类路径上的内容视为“未命名模块”,它无法被具名模块通过
显式依赖:
如果目标模块实际在 classpath 上(比如旧版 Spring Boot 打包方式),则
无效,应改用
+ 运行时反射,或迁移到纯模块化部署
执行
,若返回
,说明它不在模块路径上;若返回
,说明它是自动模块(automatic module),此时
可用,但模块名取自 JAR 文件名(不含扩展名),需严格对应
验证 exports 语句是否覆盖正确包路径
是按包(package)粒度控制的,且不递归包含子包:
若提供方写
,则
中的类仍不可见,需额外写
若消费方尝试访问的是
类中的
成员,还需确认该类是否在
的包内——
控制的是“包可见性”,不是“成员可见性”
使用
查看该模块实际依赖了哪些其他模块,辅助判断是否遗漏了间接依赖
exportsrequiresjava --list-modules | grep -i "目标模块名"--module-pathmodule-info.java--show-module-resolutionrequire failed: module 目标模块名 not foundrequiresmodule-info.javamodule xxx.yyyrequires com.example.util@1.2;requires com.example.util;module com.example.util.core { ... }--module-path-cp--class-pathrequiresrequiresrequires staticjava --describe-module 目标模块名Module xxx not foundno module descriptorrequiresexportsexports com.example.util;com.example.util.helperexports com.example.util.helper;publicprotectedexportsexportsjdeps --list-deps --module 目标模块名