SystemStubs设环境变量报InaccessibleObjectException解决方法
SystemStubs设置环境变量报模块访问异常解决方案
核心问题本质是两点:一是IDE/Maven运行时实际用了JDK9+版本而非配置的JDK1.8,二是旧版SystemStubs的反射逻辑、参数配置位置/内容不对、静态字段初始化时机错误共同导致异常,按以下步骤逐一排查修复:
1. 先确认测试运行时的实际JDK版本
绝大多数这类报错都是JDK配置不生效导致的,不要只看项目SDK配置:
- 打开IDEA设置
File -> Settings -> Build, Execution, Deployment -> Build Tools -> Maven -> Runner,将JRE选择为本地安装的JDK1.8,不要使用IDEA自带的高版本JBR(JetBrains Runtime,默认是11/17版本,是触发模块报错的最常见原因) - 打开
Run -> Edit Configurations,找到对应JUnit测试配置,将JRE选项同样指定为本地JDK1.8 - 临时在测试方法里加一行打印代码验证版本:
运行测试后控制台输出为System.out.println(System.getProperty("java.version"));1.8.0_xxx才说明JDK配置正确,JDK1.8没有模块系统限制,不会出现InaccessibleObjectException报错。
注意:不要跳过版本验证步骤,模块访问异常是JDK9+专属报错,只要出现这个错误就说明运行时用的绝对不是JDK1.8
2. 必须使用高版本JDK运行时的依赖修复
如果因业务需求必须用JDK9+版本跑测试,直接升级SystemStubs依赖到兼容高版本JDK的版本,1.x版本和旧的system-lambda依赖反射逻辑写死,仅加--add-opens参数无法解决问题,在pom.xml中替换测试依赖为:
<dependency> <groupId>uk.org.webcompere</groupId> <artifactId>system-stubs-jupiter</artifactId> <version>2.1.6</version> <scope>test</scope> </dependency>
3. 正确配置模块开放参数
升级依赖后如果仍有模块访问报错,按运行场景补全参数,不要只加java.util的开放规则:
- IDEA直接运行测试:在对应测试配置的
VM options中填入完整参数:--add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED - Maven命令行执行
mvn test:在maven-surefire-plugin中配置参数,注意如果对接了Jacoco等会修改启动参数的插件,要加@{argLine}占位符避免参数被覆盖:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M7</version> <configuration> <argLine> @{argLine} --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED </argLine> </configuration> </plugin>
4. 修正测试类的字段初始化逻辑
你当前将EnvironmentVariables声明为static静态字段并直接初始化,会绕过JUnit5扩展的生命周期管理,在扩展注入前就触发环境变量修改的反射逻辑,很容易触发报错,去掉static修饰符,在测试初始化方法里赋值即可:
@ExtendWith(SystemStubsExtension.class) class MyClass { @SystemStub private EnvironmentVariables variables; @BeforeEach void setUp() { variables.set("username", "admin"); variables.set("password", "qwerty"); } // 编写具体测试方法 }
所有配置修改完成后,执行Build -> Rebuild Project清空IDEA编译缓存,再运行测试即可正常通过。
内容的提问来源于stack exchange,提问作者DieDen
相关产品推荐
相关产品推荐

