Gradle默认不识别module-info.java,必须显式启用模块路径支持并正确放置该文件于src/main/java根目录下;仅设modularity.inferModulePath.set(true)不够,须引入org.javamodularity.moduleplugin插件处理自动模块依赖与路径组装。

Gradle 默认不识别 module-info.java,必须显式启用模块路径支持,否则编译失败或生成的 JAR 不含模块描述符。
module-info.java 放错位置会导致编译通过但模块无效
文件必须放在 src/main/java 的**最顶层目录下**,和包目录(如 com/example/...)同级。如果误放进某个子包里(比如 src/main/java/com/example/module-info.java),javac 会把它当成普通类源码,编译出 module-info.class,但 JVM 运行时不会将其识别为模块声明——结果是“有模块名、无模块行为”。
- 正确路径:
src/main/java/module-info.java - 错误路径:
src/main/java/com/example/module-info.java或src/main/java/module-info/ModuleInfo.java - 验证方式:解压生成的 JAR,检查根目录是否存在
module-info.class;不存在即说明未被编译进模块结构
Gradle 8.1+ 必须用 moduleplugin 补全模块路径推断
仅配置 java { modularity.inferModulePath.set(true) } 不够。该设置只启用基础推断,但无法处理传统 JAR(如 REngine、Rserve)作为自动模块的命名与路径注入问题,直接导致 error: module not found: REngine。
- 必须添加插件:
id("org.javamodularity.moduleplugin") version "1.8.12" - 该插件会自动将
implementation依赖从--class-path移至--module-path,并标准化自动模块名(如把org.rosuda.rengine映射为REngine) - 不加此插件时,
requires REngine;在module-info.java中永远解析失败,无论依赖是否已声明
exports / opens / requires 的写法直接影响运行时行为
导出包、开放反射、声明依赖这三类语句不是可有可无的修饰,而是 JVM 加载时强制执行的边界控制规则。
-
exports com.example.service;:外部模块才能 import 这个包里的 public 类;不写则编译期报错 “package is not visible” -
opens com.example.config;:仅允许反射访问该包内类;若用 Jackson 反序列化com.example.config.Config但没opens,运行时报IllegalAccessError -
requires static org.junit.jupiter.api;:测试依赖不参与主模块图构建,避免生产环境意外引入测试类 -
requires transitive com.fasterxml.jackson.core;:下游模块引用本模块时,自动获得对 Jackson 的访问权,省去重复声明
混合模块环境最容易忽略的类加载陷阱
当项目同时存在命名模块(含 module-info.class)、自动模块(传统 JAR 放在 --module-path)和匿名模块(JAR 放在 --class-path)时,JVM 类加载器行为不可预测——尤其是 ServiceLoader 和反射调用。
- 不要混用
--class-path和--module-path启动应用;Gradle 构建后应统一走模块路径 - 第三方库若无
module-info.class,必须确保它被插件识别为自动模块,而不是退化成匿名模块 -
opens ... to比单纯opens更安全:例如opens com.example.model to com.fasterxml.jackson.databind;限定只有 Jackson 能反射访问,而非所有模块
module-info.java 不是装饰性配置,它是 JVM 执行时的真实契约。写错一行 exports 或漏加一个插件,都可能让应用在 CI 环境跑通、本地启动失败,或者上线后某天突然抛出 NoClassDefFoundError ——因为模块边界比你想象中更硬。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











