java.lang.ClassNotFoundException: java.lang.constant.Constable after upgrading libraries

1.7k Views Asked by At

I have an application running in Tomcat 9.0.45 with JDK 11 (OpenJDK 11.0.11).

After upgrading some libraries (Spring 4.3.30 to 5.3.9) using maven, the application throws the following Exception:

java.lang.NoClassDefFoundError: java/lang/constant/Constable
    at my.app.SomeClass.process(SomeClass.java:123) ~[classes/:?]
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) [spring-context-5.3.9.jar:5.3.9]
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
    at java.base/java.lang.Thread.run(Thread.java:829) [?:?]
Caused by: java.lang.ClassNotFoundException: java.lang.constant.Constable
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1364) ~[catalina.jar:9.0.45]
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1187) ~[catalina.jar:9.0.45]
    ... 11 more

Obviously, it tries to run JRE 12 code in a JRE 11 environment.

As the Exception does not occur prior to updating the libraries, I guess some dependency got into the project that uses the JRE 12 code.

How can I find out which library/dependency causes the problem?

WebappClassLoaderBase debug log does not give any new information:

org.apache.catalina.loader.WebappClassLoaderBase.loadClass loadClass(java.lang.constant.Constable, false)
org.apache.catalina.loader.WebappClassLoaderBase.loadClass   Searching local repositories
org.apache.catalina.loader.WebappClassLoaderBase.findClass     findClass(java.lang.constant.Constable)
org.apache.catalina.loader.WebappClassLoaderBase.findClass     --> Returning ClassNotFoundException

Strangely, the Exception does not occur on my dev machine, so I also can't debug.

Any ideas are very much appreciated.

Edit: compiling with maven 3.8.1 using aspectj-maven-plugin 1.12.6.

2

There are 2 best solutions below

2
Manuel M On BEST ANSWER

@Stephen C pointed to the right direction - something has compiled something that way.

Turns out the machine that compiles the code, did not have Java 11 installed, but Java 16. (Still, that compiled perfectly runnable Java 11 code for Spring 4.3.30.)

I have removed Java 16 from the machine and installed Java 11 only. The code now runs without throwing the ClassNotFoundException.

As of why that happened, I still have no idea.

3
Stephen C On

The Constable interface (javadoc) was only added in Java 12.

So, your theory that the exception / stacktrace is caused by trying to run Java 12+ code on Java 11 is correct.

It is not entirely clear why this has happened. While the most recent versions of Spring are compatible with Java 16 ... they should also run on Java 11 (and indeed Java 8). It is possible that the Spring team have messed up and shipped some JARs that have been built incorrectly. But I doubt it.

I suspect that you have made a mistake in building your code. Maybe you compiled with a Java 12+ tool chain, against the Java SE 12+ runtime using a target version of Java 11?