Java 9+模块化需显式声明module-info.java并正确配置构建工具:该文件必须置于src/main/java根目录,Maven需用maven-compiler-plugin指定<release>≥9,运行时须用--module-path而非-classpath。

Java 9+ 的模块化系统(JPMS)不是单纯靠 Maven 多模块就能实现的——它需要在代码层显式声明模块关系,同时构建工具必须正确识别和处理 module-info.java。Maven 本身不提供“模块化项目模板”,而是通过插件、路径配置和约定配合 JDK 的模块机制来支持。
确保 JDK 和编译器插件支持 Java 9+
项目必须使用 JDK 9 或更高版本(如你当前可用的 JDK 22.0.2),且 Maven 编译插件需明确启用模块化支持:
- 使用
maven-compiler-plugin3.6.1 或更新版本(推荐 3.12.0+) - 在
pom.xml中强制指定<release>或<source>/<target>为 9 及以上,否则module-info.java可能被跳过编译 - 示例配置:
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.0</version>
<configuration>
<release>22</release>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
正确组织模块结构与 module-info.java
Maven 多模块项目 ≠ Java 模块项目。一个 Java 模块必须包含 src/main/java/module-info.java,且该文件必须位于源码根路径下(即 src/main/java/ 目录内,不能在子包中)。
- 每个 Java 模块对应一个 Maven 子模块(推荐但非强制)
-
module-info.java中的模块名通常为小写groupId.artifactId(如com.example.user.api),点号保留,不转义 - 模块间依赖必须用
requires显式声明;导出包用exports;反射访问需opens - 例如,一个服务实现模块要使用 API 模块,其
module-info.java应含:requires com.example.user.api;
区分四种模块类型并适配依赖管理
Maven 构建时,JAR 包在运行时会被 JVM 归类为以下一种模块类型,影响可见性:
立即学习“Java免费学习笔记(深入)”;
-
命名模块:含
module-info.class的 JAR,可完整参与 JPMS(推荐自建模块采用此形式) -
自动模块:旧版 JAR 放入模块路径(
--module-path)后,JVM 自动推导模块名(通常为 JAR 文件名去扩展名,或Automatic-Module-NameMANIFEST 属性) -
平台模块:JDK 自带模块(如
java.base、java.sql),直接requires即可 -
未命名模块:传统类路径(
-cp)下的所有内容,对命名模块不可见——这意味着仅靠<dependency>声明不够,还必须在module-info.java中requires对应模块名
避免常见运行时错误(如 NoClassDefFoundError)
即使 Maven 成功下载依赖、IDE 无报错,模块化项目仍常因封装限制失败。关键检查点:
- 确认被依赖的 JAR 是命名模块或自动模块(解压看是否有
module-info.class或 MANIFEST 中有Automatic-Module-Name) - 若引用的是自己开发的 Maven 模块(如
com.mavenproject1),必须在客户端module-info.java中写requires com.mavenproject1; - JavaFX 等框架模块需显式
requires javafx.controls等,不能只靠javafx-maven-plugin - 使用
--module-path启动应用(而非-cp),Maven 打包时推荐用maven-jar-plugin配置Modules属性或生成模块化 JAR


















