2

I am trying to upgrade a project from Java 8 to Java 17. I am getting following error when to trying to bring up the service and not sure how to fix it. I have searched for java.lang.IllegalAccessError issues and all I see are related to Powermock. Javassist library is not explicitly specified, but Gradle using the latest version available(org.javassist:javassist:3.28.0-GA) and I don't see multiple versions loaded. I tried --illegal-access=permit VM option, but didn't work. Any ideas or suggestion? Thanks in advance.

As part of Java 8 to 17 upgrade, I upgraded all the important libraries to the latest version including Dropwizard framework suit, Lombok, Apache Spark, Swagger, and etc.

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)

Edit: As per the suggestion, now I am upgrading my project to Java 17. But I still got the same error and stack trace.

siva
  • 53
  • 1
  • 10
  • 1
    I'm guessing you'll still have the problem but Java 12 stopped being supported 3 years ago. Java 11 and 17 are the current "long term support" releases. I'd start by not spending any more time on Java 12 and move to Java 17. Again, it's likely you'll still have the issue. Are you sure that all of the libraries you're using support releases past Java 8? – stdunbar Dec 30 '22 at 17:41
  • 1
    Related to that, if you updated all libraries to their latest version, it's a good bet you updated them to versions that require a java that's many major versions newer than 12. If you absolutely need java 12, update them to "not the latest version" and instead find the versions that were released to target java 12. But the above advise should take precedence: update to java 17 instead if you can. – Mike 'Pomax' Kamermans Dec 30 '22 at 17:42
  • Even I wanted to upgrade to Java 17, but I have dependency on AWS EMR. The latest version of emr-6.9.0 supports Java 12 - https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-690-release.html. Yes, I made sure of the java version supports when upgrading the libraries. – siva Dec 30 '22 at 18:35
  • I see nothing related to the Java version. I see a dependency on the AWS SDK of 1.12.x but not Java. This was release in December of 2022 - no way AWS is having you have a dependency on a test version of Java. Did I miss it somewhere? – stdunbar Dec 30 '22 at 18:48
  • My bad. I read it as only Java 12 is supported by emr. I will try running my project with java 17. Thanks for pointing it out. – siva Dec 30 '22 at 19:14
  • @stdunbar I changed my project JDK to version 17, but I still got same error and stack trace :( . Do you have any pointers based on the stack trace? Thanks – siva Dec 31 '22 at 00:26
  • 1
    I think this is the solution: https://stackoverflow.com/a/72172132/139985. (It says 3.29.x is not ready ... but that is out of date. See https://github.com/jboss-javassist/javassist/releases). – Stephen C Dec 31 '22 at 01:02
  • You need to upgrade your libraries or dependencies to those that support recent Java versions. – CaptainPyscho Dec 31 '22 at 03:05
  • Thanks @StephenC. It's exactly the same issue I am having. I already upgraded Javassist lib to 3.29.2-GA which is latest and greatest version, but I still having the issue. – siva Jan 01 '23 at 08:00
  • Of course an upgrade to a version working without opening JDK modules would be the best. But just in case that does not work, what happens if you try `--add-opens java.base/jdk.internal.reflect=ALL-UNNAMED?` – kriegaex Jan 01 '23 at 10:39

1 Answers1

1

This is the problem:

https://learn.microsoft.com/en-us/java/openjdk/transition-from-java-8-to-java-11

In Java 11, using reflection to access to JDK-internal API will result in an illegal reflective access warning. By default, the warning is only issued for the first illegal access. Setting --illegal-access=warn will cause a warning on every illegal reflective access. You will find more case if illegal access with the option set to warn. But you will also get a lot of redundant warnings. Once the application runs on Java 11, set --illegal-access=deny to mimic the future behavior of the Java runtime. Starting with Java 16, the default will be --illegal-access=deny.

Up thorugh Java 16, the workaround has been --illegal-access=permit, but apparently that's no longer an option:

https://github.com/NationalSecurityAgency/ghidra/issues/3355

JDK 17: --illegal-access=permit removed #3355

This post discusses the background behind and rationale for introducing this "breaking change":

https://blogs.oracle.com/javamagazine/post/a-peek-into-java-17-continuing-the-drive-to-encapsulate-the-java-runtime-internals

paulsm4
  • 114,292
  • 17
  • 138
  • 190