升级至Java 21后ArchUnit报Unsupported class file major version 65求助
问题:Java 21升级后ArchUnit架构测试报错(Unsupported class file major version 65)
将项目从Java 11升级到Java 21后,运行ArchUnit架构测试时持续抛出非法参数异常,核心错误为java.lang.IllegalArgumentException: Unsupported class file major version 65。当前环境配置:
- Gradle版本:8.6(已在gradle-wrapper文件中配置)
- JDK版本:21
- 曾尝试将Gradle JVM切换为17,但问题未得到解决
完整错误堆栈:
java.lang.IllegalArgumentException: Unsupported class file major version 65 at com.tngtech.archunit.thirdparty.org.objectweb.asm.ClassReader.<init>(ClassReader.java:199) at com.tngtech.archunit.thirdparty.org.objectweb.asm.ClassReader.<init>(ClassReader.java:180) at com.tngtech.archunit.thirdparty.org.objectweb.asm.ClassReader.<init>(ClassReader.java:166) at com.tngtech.archunit.thirdparty.org.objectweb.asm.ClassReader.<init>(ClassReader.java:287) at com.tngtech.archunit.core.importer.ClassFileProcessor.process(ClassFileProcessor.java:65) at com.tngtech.archunit.core.importer.ClassFileImporter.importLocations(ClassFileImporter.java:336) at com.tngtech.archunit.core.importer.ClassFileImporter.importPackages(ClassFileImporter.java:209) at com.tngtech.archunit.core.importer.ClassFileImporter.importPackages(ClassFileImporter.java:220) at tech.seedz.contract.architecture.ArchitectureTest.setup(ArchitectureTest.java:22) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:728) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptLifecycleMethod(TimeoutExtension.java:128) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptBeforeEachMethod(TimeoutExtension.java:78) at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103) at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92) at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeMethodInExtensionContext(ClassBasedTestDescriptor.java:520) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$synthesizeBeforeEachMethodAdapter$23(ClassBasedTestDescriptor.java:505) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachMethods$3(TestMethodTestDescriptor.java:174) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$6(TestMethodTestDescriptor.java:202) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:202) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachMethods(TestMethodTestDescriptor.java:171) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:134) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
解决方案
升级ArchUnit至兼容Java 21的版本
错误本质是ArchUnit内置的ASM库版本过低,不支持Java 21对应的类文件主版本65。需要将ArchUnit依赖升级到1.2.1及以上版本(该版本开始正式支持Java 21)。
在Gradle中更新依赖:testImplementation 'com.tngtech.archunit:archunit-junit5:1.2.1' // 若使用JUnit 4,替换为:testImplementation 'com.tngtech.archunit:archunit-junit4:1.2.1'统一项目编译的JDK版本配置
检查build.gradle中的Java编译设置,确保源码和目标兼容性都指定为21,避免生成混合版本的类文件:java { sourceCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_21 }确保Gradle运行时使用JDK 21
之前切换到JDK 17无效,是因为测试需要处理Java 21编译的类文件。可以通过以下方式指定Gradle使用的JDK:- 在项目根目录的
gradle.properties中添加:org.gradle.java.home=/path/to/your/jdk21 - 在IDE(如IntelliJ IDEA)的Gradle设置中,将Gradle JVM改为JDK 21。
- 在项目根目录的
内容的提问来源于stack exchange,提问作者Hadi Kattan
相关产品推荐
相关产品推荐

