必须写对模块名而非包名或maven坐标;模块名由jar中module-info.class显式声明,需通过源码、jar命令或javap验证,且jar须含module-info.class、构建与运行均启用模块路径。

在 Java 9+ 模块系统中,声明 requires 依赖关系的核心是:**必须写对模块名(module name),而不是包名或 Maven 坐标**。模块名由被依赖 JAR 中的 module-info.class 显式声明,编译器只认这个名称。
一、requires 的基本写法和常见错误
requires 语句写在 module-info.java 文件里,位于模块声明块内。例如:
✅ 正确示例:
module stock.core {
requires java.base; // JDK 内置模块,可省略但合法
requires com.github.benmanes.caffeine; // Caffeine 的真实模块名
requires java.logging; // 使用日志时需显式声明
}
❌ 典型错误:
- 写成包名:
requires com.github.benmanes.caffeine.cache;→ 编译报错 “Module not found” - 写成 Maven 坐标:
requires caffeine;或requires com.github.benmanes:caffeine;→ 无效语法 - 漏掉 module-info.class:即使名字写对,若 JAR 不含该文件,JVM 无法识别为命名模块
二、怎么查第三方库的真实模块名
不能靠猜,也不能看包结构。可靠方法有三种:
- 查看该库 GitHub 上的
module-info.java源码(如 Caffeine 在 master/caffeine/src/main/java/module-info.java) - 解压 JAR,检查是否存在
module-info.class:jar -tf caffeine-3.1.6.jar | grep module-info - 用
javap -v查看模块声明:javap -v -cp caffeine-3.1.6.jar 'module-info' | grep "Module:"
三、requires transitive 的使用场景
当你开发的是一个被其他模块使用的库(比如工具模块),且希望它的依赖也“透传”给使用者时,就加 transitive:
module com.example.utils {
requires transitive com.github.benmanes.caffeine; // 使用者也能直接用 Cache 接口
requires java.time;
}
这样,另一个模块只要写 requires com.example.utils;,就自动获得对 Caffeine 的访问权,无需重复声明。
四、必须满足的三个前提条件
光写对 requires 不够,以下三点缺一不可:
- JAR 包内含有效的
module-info.class(Caffeine ≥ 2.9、Jackson 2.12+、SLF4J 2.0+ 等较新版本已支持) - Maven 构建时启用模块路径:确保
maven-compiler-plugin配置了<release>11</release>或明确使用--module-path - 运行时也要用模块路径启动,而非传统类路径:
java --module-path mods --module stock.core/com.example.Main
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











