JDK17反射读取EnumSet字段报错,配置--add-opens编译失败如何解决
问题原因
- 初始的
InaccessibleObjectException是JDK 9+模块化系统的默认限制:未命名模块(你的应用代码)默认无权反射访问JDK内部的java.util.EnumSet私有字段,需要通过--add-opens参数在运行时放开权限。 - 后续的
invalid flag报错有两个直接原因:- 你把运行时才需要的
--add-opens参数错误配置到了maven-compiler-plugin的编译参数中,且你配置的编译目标版本是JDK 8,JDK 8本身不识别--add-opens参数,直接触发编译错误。 - maven-surefire-plugin里配置了多个
<argLine>标签,后定义的会覆盖前一个,导致只有最后一个参数生效,无法同时放开两个包的访问权限。
- 你把运行时才需要的
解决方案
第一步:移除编译插件的错误参数
删除maven-compiler-plugin配置里的整个<compilerArgs>块,编译阶段不需要加运行时参数。
第二步:修正测试插件的参数配置
将两个--add-opens参数合并到同一个<argLine>标签内,同时建议将maven-surefire-plugin版本升级到3.0.0-M5及以上,保证对JDK 17的兼容性。
正确配置参考:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <!-- 版本建议至少为3.0.0-M5,可自行调整为更高稳定版 --> <version>3.2.2</version> <configuration> <argLine> --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED </argLine> </configuration> <executions> <execution> <goals> <goal>test</goal> </goals> <inherited /> </execution> </executions> </plugin>
可选优化(推荐)
如果不想依赖JDK内部字段反射,可以修改测试逻辑避免权限问题:比如在构造SetOfEnumUserType时直接传入枚举类类型,测试时直接比对传入的类型即可,不需要通过反射读取EnumSet的私有字段。
内容的提问来源于stack exchange,提问作者user1191027
相关产品推荐
相关产品推荐

