问题描述
我有一个应用程序在 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
。
至于为什么会这样,我仍然不知道。