迁移至JDK 17后Rest Assured测试代码运行异常求助
问题
我们正在构建带测试用例的REST API,API本身运行正常,但测试环节出错:
- 测试使用Rest Assured库,因组织要求必须使用JDK 17
- 升级至JDK 17后,运行Rest Assured测试时触发
java.lang.ExceptionInInitializerError,怀疑与JDK 17的反射限制有关 - 出错代码:
RestAssured.baseURI = Constants.BASE_URI; RestAssured.port = Constants.PORT; RestAssured.basePath = Constants.BASE_PATH;
这段代码用于为所有测试设置baseURI、port和basePath,此前运行正常,迁移到JDK 17后出现问题,且无法更换Java版本,需要可行的解决方案。
错误栈信息:
java.lang.ExceptionInInitializerError at io.restassured.builder.RequestSpecBuilder.<init>(RequestSpecBuilder.java:79) at com.teamcenter.services.strong.utils.TestBase.createRequestSpecification(TestBase.java:99) at com.teamcenter.services.strong.utils.TestBase.createRequestSpecification(TestBase.java:82) at com.teamcenter.services.strong.utils.TestBase.setUp(TestBase.java:116) at com.teamcenter.services.strong.IncludeRuleTest.setUp(IncludeRuleTest.java:36) at junit.framework.TestCase.runBare(TestCase.java:140) at junit.framework.TestResult$1.protect(TestResult.java:122) at junit.framework.TestResult.runProtected(TestResult.java:142) at junit.framework.TestResult.run(TestResult.java:125) at junit.framework.TestCase.run(TestCase.java:130) at junit.framework.TestSuite.runTest(TestSuite.java:241) at junit.framework.TestSuite.run(TestSuite.java:236) at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:90) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:93) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210) Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make java.lang.String(char[],int,int,java.lang.Void) accessible: module java.base does not "opens java.lang" to unnamed module @3cda1055 at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) at java.base/java.lang.reflect.Constructor.checkCanSetAccessible(Constructor.java:188) at java.base/java.lang.reflect.Constructor.setAccessible(Constructor.java:181) at org.codehaus.groovy.reflection.CachedConstructor$1.run(CachedConstructor.java:44) at java.base/java.security.AccessController.doPrivileged(AccessController.java:318) at org.codehaus.groovy.reflection.CachedConstructor.<init>(CachedConstructor.java:42) at org.codehaus.groovy.reflection.CachedClass$2.initValue(CachedClass.java:79) at org.codehaus.groovy.reflection.CachedClass$2.initValue(CachedClass.java:69) at org.codehaus.groovy.util.LazyReference.getLocked(LazyReference.java:49) at org.codehaus.groovy.util.LazyReference.get(LazyReference.java:36) at org.codehaus.groovy.reflection.CachedClass.getConstructors(CachedClass.java:268) at groovy.lang.MetaClassImpl.<init>(MetaClassImpl.java:218) at groovy.lang.MetaClassImpl.<init>(MetaClassImpl.java:228) at groovy.lang.MetaClassRegistry$MetaClassCreationHandle.createNormalMetaClass(MetaClassRegistry.java:171) at groovy.lang.MetaClassRegistry$MetaClassCreationHandle.createWithCustomLookup(MetaClassRegistry.java:161) at groovy.lang.MetaClassRegistry$MetaClassCreationHandle.create(MetaClassRegistry.java:144) at org.codehaus.groovy.reflection.ClassInfo.getMetaClassUnderLock(ClassInfo.java:253) at org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:285) at org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:295) at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.getMetaClass(MetaClassRegistryImpl.java:261) at org.codehaus.groovy.runtime.InvokerHelper.getMetaClass(InvokerHelper.java:873) at org.codehaus.groovy.runtime.callsite.CallSiteArray.createPojoSite(CallSiteArray.java:125) at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallSite(CallSiteArray.java:166) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at io.restassured.internal.RequestSpecificationImpl.<clinit>(RequestSpecificationImpl.groovy:86) ... 19 more
解决方案
升级Rest Assured到兼容JDK 17的版本
旧版本Rest Assured依赖的Groovy版本不支持JDK 17的模块系统,直接升级到5.x及以上的稳定版即可,这类版本已修复JDK 17的反射访问问题,无需额外配置。添加JVM参数绕过模块限制(临时方案)
如果暂时无法升级库版本,可在测试的JVM启动参数中添加以下配置,允许Groovy访问Java模块内部API:--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED根据构建工具不同配置位置不同:
- Maven:在
pom.xml的maven-surefire-plugin中添加argLine参数 - Gradle:在
test任务中配置jvmArgs
- Maven:在
改用RequestSpecBuilder替代静态全局配置
避免直接使用Rest Assured的静态全局配置,改用RequestSpecBuilder创建请求规范,绕过静态初始化时的反射问题:RequestSpecification spec = new RequestSpecBuilder() .setBaseUri(Constants.BASE_URI) .setPort(Constants.PORT) .setBasePath(Constants.BASE_PATH) .build(); // 测试中使用该规范 given().spec(spec)...
内容的提问来源于stack exchange,提问作者Dhiraj Shetty
相关产品推荐
相关产品推荐

