Java 8升级至Java 17遭遇java.lang.IllegalAccessError问题求助
项目从Java 8升级至Java 17启动报错:IllegalAccessError
问题背景
正在将项目从Java 8升级到Java 17,启动服务时触发java.lang.IllegalAccessError错误。搜索相关问题后发现这类错误大多与Powermock有关,但项目未显式引入Javassist库,Gradle使用的是最新版本org.javassist:javassist:3.28.0-GA,且不存在多版本加载情况。尝试添加VM选项--illegal-access=permit,但未解决问题。
已完成的升级操作:作为Java 8转17升级工作的一部分,已将Dropwizard框架、Lombok、Apache Spark、Swagger等核心依赖升级至最新版本。
编辑说明:按建议完成Java 17相关升级后,仍出现完全相同的错误及堆栈信息。
错误堆栈信息
java.lang.IllegalAccessError: class jdk.internal.reflect.ConstructorAccessorImpl loaded by com.company.custom.metadata.run.CompanyLoader @f2ff811 cannot access jdk/internal/reflect superclass jdk.internal.reflect.MagicAccessorImpl at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:877) at javassist.Loader.findClass(Loader.java:419) at javassist.Loader.loadClass(Loader.java:350) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.System$2.defineClass(System.java:2189) at java.base/jdk.internal.reflect.ClassDefiner.defineClass(ClassDefiner.java:65) at java.base/jdk.internal.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:400) at java.base/jdk.internal.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:394) at java.base/java.security.AccessController.doPrivileged(AccessController.java:310) at java.base/jdk.internal.reflect.MethodAccessorGenerator.generate(MethodAccessorGenerator.java:393) at java.base/jdk.internal.reflect.MethodAccessorGenerator.generateConstructor(MethodAccessorGenerator.java:92) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:55) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481) at org.jboss.logging.Logger.doGetMessageLogger(Logger.java:2573) at org.jboss.logging.Logger.getMessageLogger(Logger.java:2530) at org.jboss.logging.Logger.getMessageLogger(Logger.java:2516) at org.hibernate.validator.internal.util.logging.LoggerFactory.make(LoggerFactory.java:22) at org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.<clinit>(ValidatorFactoryConfigurationHelper.java:51) at org.hibernate.validator.internal.engine.ValidatorFactoryImpl.<init>(ValidatorFactoryImpl.java:135) at org.hibernate.validator.HibernateValidator.buildValidatorFactory(HibernateValidator.java:38) at org.hibernate.validator.internal.engine.AbstractConfigurationImpl.buildValidatorFactory(AbstractConfigurationImpl.java:433) at io.dropwizard.jersey.validation.Validators.newValidatorFactory(Validators.java:26) at io.dropwizard.setup.Bootstrap.<init>(Bootstrap.java:67) at io.dropwizard.Application.run(Application.java:86) at com.company.api.CompanyService.main(CompanyService.java:571) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:567) at javassist.Loader.run(Loader.java:328) at com.company.custom.metadata.CompanyServiceRun.run(CompanyServiceRun.java:151) at com.company.custom.metadata.CompanyServiceRun.main(CompanyServiceRun.java:198)
解决思路
- 排查自定义类加载器逻辑:错误显示
com.company.custom.metadata.run.CompanyLoader这个自定义类加载器尝试加载JDK内部类jdk.internal.reflect.ConstructorAccessorImpl,但Java 9+模块系统下,自定义类加载器不应加载JDK内部类。需修改该类加载器,让JDK内部类由系统类加载器处理,避免越权加载。 - 升级Javassist至兼容版本:当前使用的3.28.0-GA可能对Java 17的模块系统兼容不足,建议升级到3.29.0-GA及以上版本,新版本通常修复了高版本Java的类访问权限问题。
- 校验Hibernate Validator版本兼容性:错误从Hibernate Validator初始化触发,需确保其版本同时兼容Java 17和当前Dropwizard版本。检查Dropwizard与Hibernate Validator的依赖适配关系,调整版本消除冲突。
- 替换废弃的VM选项:Java 17已移除
--illegal-access=permit选项(Java 16起已废弃),可临时添加--add-opens java.base/jdk.internal.reflect=ALL-UNNAMED参数允许访问内部包,但这只是临时方案,建议从类加载器和依赖版本层面解决根本问题。 - 排查隐式引入的Powermock依赖:项目未显式使用Powermock,但可能通过其他依赖间接引入。执行
gradle dependencies查看依赖树,若发现Powermock相关依赖,要么排除,要么升级到兼容Java 17的版本。
内容的提问来源于stack exchange,提问作者siva
相关产品推荐
相关产品推荐

