在maven多模块项目中启用java 9模块化需规范结构、升级编译插件并正确编写module-info.java:父模块packaging为pom,子模块须含module-info.java;使用maven-compiler-plugin 3.6.1+并设9;requires需用模块名而非maven坐标,注意自动模块兼容与循环依赖。

在 Maven 多模块项目中启用 Java 9 模块化(JPMS),关键不是“只加 module-info.java”,而是让整个构建链路识别模块路径、正确编译并处理模块依赖。Maven 本身不原生管理 Java 模块,需靠插件协同和结构规范来桥接。
确保父模块与子模块结构合规
Java 9 模块系统对目录结构无强制要求,但 Maven 多模块有硬性约定:
- 父模块 packaging 必须为 pom,且
<modules></modules>中显式声明所有子模块路径 - 所有子模块目录必须位于父模块目录下,不能跨级或外挂
- 每个子模块的
pom.xml中<parent></parent>必须完整指定 groupId/artifactId/version,并推荐显式写<relativepath></relativepath> - 子模块若要成为命名模块(即参与 JPMS),必须在
src/main/java根目录下放置module-info.java
配置支持 Java 9+ 的编译插件
Maven 默认插件版本较旧,无法识别 module-info.java 或处理模块路径。必须升级并显式配置:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 使用
maven-compiler-plugin 3.6.1+,并在<configuration></configuration>中指定<release>9</release>或<source>9</source><target>9</target> - 建议统一在父模块的
<pluginmanagement></pluginmanagement>中声明插件版本和基础参数,子模块在自身<build><plugins></plugins></build>中引用即可生效 - 避免混用
<source>/<target></target></source>和<release></release>;<release></release>更安全,能保证 API 兼容性
子模块中编写有效的 module-info.java
每个想作为命名模块的子模块,需在 src/main/java/module-info.java 中声明其角色:
- 用
requires声明所依赖的模块:对 JDK 模块(如java.sql)直接写名;对外部库(如com.fasterxml.jackson.core),需确保该库已发布为模块(或 Maven 会将其转为自动模块) - 用
exports明确导出哪些包给其他模块使用;未导出的包默认不可见 - 若模块需被反射访问(如 Spring、Jackson 序列化),用
opens或opens ... to开放特定包 - 注意:Maven 子模块之间依赖 ≠ Java 模块依赖。即使 A 依赖 B 的 Maven 坐标,A 的
module-info.java仍需显式requiresB 的模块名
处理模块间依赖与自动模块兼容
现实项目中大量第三方库尚未模块化,它们在模块路径上会变成“自动模块”:
- 自动模块名通常由 JAR 文件名推导(如
guava-32.1.3-jre.jar→ 模块名com.google.common),可通过jmod describe xxx.jar或运行时--list-modules查看 - 在
module-info.java中requires自动模块时,必须用其推导出的模块名,而非 Maven 坐标 - 若某子模块仅作资源/配置提供(不含 Java 类),可不写
module-info.java,它会被视为未命名模块;其他模块通过 Maven 依赖仍可加载其src/main/resources下的文件 - 避免循环 requires:A requires B 且 B requires A 在编译期会报错,需通过接口抽象或引入第三个模块解耦
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










