You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Java 17升级至Java 21时遭遇UnsupportedOperationException问题求助

Java 21升级后Serenity + Cucumber测试反射权限错误解决方法

我的代码基于cucumber-java8和Serenity框架开发,在Java 17环境下执行mvn test可以正常运行Cucumber用例,但升级到Java 21后,测试抛出如下运行时错误:

Caused by: java.lang.UnsupportedOperationException: Cannot define class using reflection: Unable to make protected java.lang.Package java.lang.ClassLoader.getPackage(java.lang.String) accessible: module java.base does not "opens java.lang" to unnamed module @6bc168e5
 at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection$Dispatcher$Initializable$Unavailable.defineClass(ClassInjector.java:472)
 at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection.injectRaw(ClassInjector.java:284)
 at net.bytebuddy.dynamic.loading.ClassInjector$AbstractBase.inject(ClassInjector.java:118)
 at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$InjectionDispatcher.load(ClassLoadingStrategy.java:241)
 at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default.load(ClassLoadingStrategy.java:148)
 at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:101)
 at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6166)
 at net.serenitybdd.rest.utils.RestSpecificationFactory.<clinit>(RestSpecificationFactory.java:60)
 at net.serenitybdd.rest.utils.RestDecorationHelper.decorate(RestDecorationHelper.java:20)
 at net.serenitybdd.rest.SerenityRest.fetchRequestSpecification(SerenityRest.java:233)
 at net.serenitybdd.rest.SerenityRest.given(SerenityRest.java:220)

切换回Java 17后测试恢复正常,当前项目依赖版本配置如下:

<cucumber.version>7.9.0</cucumber.version>
<junit.version>4.13.2</junit.version>
<junit.jupiter.version>5.9.0</junit.jupiter.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<serenity.version>4.1.6</serenity.version>
<webdriver.driver>provided</webdriver.driver>
<maven.surefire.version>3.5.2</maven.surefire.version>
<java.version>21</java.version>

问题原因

Java 21对模块系统的访问控制进一步收紧,当前使用的Serenity 4.1.6版本依赖的ByteBuddy库未适配Java 21的模块权限规则,导致动态生成类时无法通过反射访问java.lang包下的受限方法。

解决方法

1. 优先升级Serenity到兼容Java 21的版本

Serenity后续版本已经修复了Java 21的兼容性问题,建议将serenity.version升级到4.1.10及以上(或最新稳定版),新版本会自动适配Java 21的模块要求,同时更新依赖的ByteBuddy版本。

修改pom.xml中的版本:

<serenity.version>4.1.12</serenity.version> <!-- 示例最新稳定版,可根据实际情况调整 -->

2. 临时 workaround:添加JVM模块开放参数(不推荐长期使用)

如果暂时无法升级依赖,可以在Maven Surefire插件中添加JVM参数,开放java.lang包的访问权限给未命名模块:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${maven.surefire.version}</version>
    <configuration>
        <argLine>
            --add-opens java.lang/java.lang=ALL-UNNAMED
            --add-opens java.base/java.lang.ClassLoader=ALL-UNNAMED
        </argLine>
    </configuration>
</plugin>

执行mvn test时,插件会自动将这些参数传递给JVM,临时绕过模块权限限制。


内容的提问来源于stack exchange,提问作者Stephen Prasad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:03:17