java.lang.ClassNotFoundException: 升级库后的 java.lang.constant.Constable

问题描述

我有一个应用程序在 Tomcat 9.0.45 和 JDK 11 (OpenJDK 11.0.11) 中运行。

使用 maven 升级一些库(Spring 4.3.30 到 5.3.9)后,应用程序抛出以下异常:

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

显然,它试图在 JRE 11 环境中运行 JRE 12 代码

由于在更新库之前不会发生异常,我猜一些依赖项进入了使用 JRE 12 代码的项目。

如何找出导致问题的库/依赖项?

WebappClassLoaderBase 调试日志没有提供任何新信息:

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

奇怪的是,我的开发机器上没有出现异常,所以我也无法调试。

非常感谢任何想法。

编辑:使用 aspectj-maven-plugin 1.12.6 编译 maven 3.8.1。

解决方法

Constable 接口 (javadoc) 仅在 Java 12 中添加。

因此,您认为异常/堆栈跟踪是由尝试在 Java 11 上运行 Java 12+ 代码引起的理论是正确的。

目前尚不清楚为什么会发生这种情况。虽然最新版本的 Spring 与 Java 16 兼容……但它们也应该在 Java 11(实际上是 Java 8)上运行。有可能是 Spring 团队搞砸了并运送了一些构建错误的 JAR。但我对此表示怀疑。

我怀疑您在构建您的代码时犯了一个错误。也许您使用 Java 12+ 工具链编译,针对 Java SE 12+ 运行时使用 Java 11 的目标版本?

,

@Stephen C 指出了正确的方向 - 有些东西就是这样编译的

原来编译代码的机器没有安装 Java 11,而是安装了 Java 16。(仍然为 Spring 4.3.30 编译了完全可运行的 Java 11 代码。)

我已经从机器上删除了 Java 16 并且只安装了 Java 11。代码现在运行时不会抛出 ClassNotFoundException

至于为什么会这样,我仍然不知道。