必须确保 module-info.java 中 exports 的包名与源码物理路径严格一致,包括大小写、点号和层级顺序;requires 模块名须与被依赖模块的 module 声明完全匹配;通过 -Xlog:module=debug 或 jdeps 验证导出与依赖关系。

直接看 module-info.java 里 exports 后面写的包名是否和实际源码包结构完全一致——大小写、点号、层级顺序,一个字符都不能错。
确认 exports 包路径与源码物理结构严格匹配
Java 模块系统要求 exports com.example.service; 必须对应磁盘上真实的目录结构:src/main/java/com/example/service/。如果代码实际放在 com/example/servcie/(少了一个 r),模块虽能编译通过,但运行时其他模块 import 该包下的类就会触发 NoClassDefFoundError 或 IllegalAccessError。
- 打开项目资源管理器,逐级展开
java源根目录,肉眼核对包路径拼写 - 特别注意易错点:service / servcie / sevice;util / utils / utill;config / confi;大小写混用如
API和api - 不要依赖 IDE 自动生成的包声明,手动比对最可靠
检查 requires 和 exports 是否成对且指向正确模块
若 A 模块 exports com.a.b,而 B 模块想使用它,B 的 module-info.java 中必须有 requires a.module.name;,且该名称必须与 A 模块的 module-info.java 中 module a.module.name { ... } 声明完全一致。
- 在 B 模块中 Ctrl+Click(或 Cmd+Click)
requires后的模块名,看能否跳转到 A 模块的module-info.java - 如果跳转失败,说明模块名不匹配或 A 模块未被正确识别为模块(比如缺少
module-info.java或编译输出未包含模块描述符) - 确保 A 模块打包为 JAR 时保留了
META-INF/MANIFEST.MF中的Automatic-Module-Name(如手动设置),或更推荐使用显式模块名
验证运行时模块图是否包含目标包
启动应用时加上 JVM 参数,让 Java 显式打印模块解析过程:
-
-Xlog:module=debug(JDK 9+)可输出模块读取、导出、读取关系 -
--show-module-resolution会列出每个类从哪个模块加载,快速定位缺失导出 - 运行后搜索关键词如
exports、com.example.service、not exported,直接看到哪一步断开
用 jdeps 工具静态分析依赖与导出关系
在项目构建完成后(如 mvn compile),用 jdeps 检查模块间可见性:
-
jdeps --module-path target/*.jar --list-deps your-app.jar查看依赖链 -
jdeps --module-path target/*.jar --print-module-deps your-app.jar输出最小模块集 - 重点观察输出中是否有
error: module X does not export Y to Z类提示
这类问题不复杂但容易忽略,关键在“所写即所得”——exports 写什么,源码就必须长什么样,中间没有容错或自动纠正。










