Java17执行mvn package报jdk.compiler模块未开放错误如何修复
问题根因
该报错由Java 9引入的JPMS模块系统强封装机制触发。Java 17默认禁止classpath下的未命名模块(即未声明module-info.java的传统Java项目)访问JDK内部非公开API,你项目构建阶段加载的某个注解处理器调用了jdk.compiler模块下com.sun.tools.javac.processing包的内部类,直接触发了访问拦截。报错信息里@后面的十六进制字符串是模块实例的哈希值,每次运行都会变化,不影响问题定位。
排查步骤
- 定位问题依赖:执行
mvn package -X开启Maven调试日志,拉到报错栈之前的注解处理器加载段,就能找到是哪个组件触发的访问,常见触发源是低版本Lombok、MapStruct、QueryDSL,或是项目自定义的编译期注解处理器 - 校验Maven运行时JDK版本:执行
mvn -v查看输出的Java版本信息,确认Maven实际调用的是你本地安装的Java 17,排除Maven配置指向旧JDK、其他发行版JDK导致的兼容性问题 - 检查maven-compiler-plugin版本:3.8.0以下版本的编译插件对Java 9+模块系统兼容性极差,哪怕依赖本身适配Java17,也可能因为插件逻辑问题抛出这类模块访问错误
修复方案
方案1:升级不兼容组件(无副作用,优先选择)
这是最彻底的解决方式,不需要额外加绕过参数:
- 若触发源是Lombok:升级到1.18.22及以上版本,该版本开始Lombok已完成Java17适配,不会再访问受限内部API
- 若触发源是MapStruct:升级到1.5.0.Final及以上版本
- 其他第三方注解处理器:替换为官方明确标注支持Java17的最新稳定版
- 同步将maven-compiler-plugin升级到3.10.1以上稳定版,最小配置参考:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>17</source> <target>17</target> </configuration> </plugin> </plugins> </build>
方案2:添加JVM参数绕过模块限制(适合依赖暂时无法升级的临时场景)
注意:该方案仅为临时兼容手段,后续JDK版本进一步收紧内部API访问权限时可能失效,优先选择升级组件的方案
通过--add-opens参数主动给未命名模块开放对应包的访问权限,有两种配置方式:
- 单次执行生效:打包命令拼接环境变量直接运行
# Linux/macOS MAVEN_OPTS="--add-opens jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED" mvn package # Windows cmd set MAVEN_OPTS="--add-opens jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED" && mvn package
- 全局生效:在系统环境变量中添加
MAVEN_OPTS配置,值为--add-opens jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED,后续所有Maven命令都会自动加载该参数
方案3:改造自定义注解处理器(针对自研组件场景)
如果是项目内部自研的注解处理器触发的报错,直接替换掉对com.sun.tools.javac.processing内部API的调用,改用javax.annotation.processing包下的标准公开API实现编译期逻辑,从根源上避免依赖JDK内部非稳定接口。
内容的提问来源于stack exchange,提问作者DasShorty
相关产品推荐
相关产品推荐

