【问题标题】:java.lang.NoClassDefFoundError for clojure.java.api.Clojureclojure.java.api.Clojure 的 java.lang.NoClassDefFoundError
【发布时间】:2020-05-13 05:36:58
【问题描述】:

我们在这里遇到了一个毫无意义的 java.lang.NoClassDefFoundError。

相同的 WAR 文件在服务器 B 中完美运行,但在服务器 A 上抛出 java.lang.NoClassDefFoundError。

配置如下:

服务器 A(抛出异常):

OS: 
    NAME="SLES"
    VERSION="12-SP4"
    VERSION_ID="12.4"
    PRETTY_NAME="SUSE Linux Enterprise Server 12 SP4"
Apache Tomcat 8.5.49
Oracle Java dk1.8.0_231

服务器 B(完美运行):

OS:
    NAME="Ubuntu"
    VERSION="16.04.6 LTS (Xenial Xerus)"
    ID=ubuntu
    ID_LIKE=debian
    VERSION_ID="16.04"
    PRETTY_NAME="Ubuntu 16.04.6 LTS"
Apache Tomcat 8.5.37
Oracle Java jdk 1.8.0_201-b09

例外是:

2020-01-27 15:57:27.103 [http-nio-8081-exec-10] ERROR o.g.w.errors.GrailsExceptionResolver - NoClassDefFoundError occurred when processing request: [GET] /server-0.1/cenario/getCenarioJson
Could not initialize class clojure.java.api.Clojure. Stacktrace follows:
org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class clojure.java.api.Clojure
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:982)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        ...
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class clojure.java.api.Clojure
        at com.nitryx.brkmopt.util.ClojureHandler.invoke(ClojureHandler.java:176)
        at com.nitryx.brkmopt.util.ClojureHandler.invoke(ClojureHandler.java:173)
        at com.nitryx.brkmopt.CenarioService.$tt__getCenarioJson(CenarioService.groovy:35)
        ...        

WAR 文件在服务器 B 上完美运行,但在服务器 A 上抛出异常。

我们检查了tomcat下的~/WEB-INF/lib/文件夹,必要的依赖(clojure-1.9.0.jar)在那里并且是一致的。在绝望的行动中,我们甚至尝试手动将 jar 文件替换为较新的文件,但没有成功。

来自Why am I getting a NoClassDefFoundError in Java?

java.lang.NoClassDefFoundError 这个异常表示JVM 查看其内部类定义数据结构 定义了一个类,并没有找到它。这不同于 说它无法从类路径加载。通常这个 表示我们之前尝试从 类路径,但由于某种原因它失败了

请指教!

编辑: 完整的堆栈跟踪:(非常感谢 clojurians @jumar @alexmiller @ghadi @seancorfield)

2020-02-05 16:00:02.342 [http-nio-8081-exec-10] ERROR o.g.w.errors.GrailsExceptionResolver - NoClassDefFoundError occurred when processing request: [GET] /server-0.1/cenario/getCenarioJson
Could not initialize class clojure.java.api.Clojure. Stacktrace follows:
org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class clojure.java.api.Clojure
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:982)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:239)
        at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:215)
        at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
        at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:239)
        at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:215)
        at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
        at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
        at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:130)
        at org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:66)
        at org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:105)
        at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:123)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class clojure.java.api.Clojure
        at com.nitryx.brkmopt.util.ClojureHandler.invoke(ClojureHandler.java:176)
        at com.nitryx.brkmopt.util.ClojureHandler.invoke(ClojureHandler.java:173)
        at com.nitryx.brkmopt.CenarioService.$tt__getCenarioJson(CenarioService.groovy:35)
        at grails.melody.plugin.MelodyInterceptorEnhancer$_enhance_closure1$_closure2.doCall(MelodyInterceptorEnhancer.groovy:77)
        at grails.gorm.transactions.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:94)
        at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
        at grails.gorm.transactions.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:91)
        at grails.melody.plugin.MelodyInterceptorEnhancer$_enhance_closure1$_closure2.doCall(MelodyInterceptorEnhancer.groovy:77)
        at com.nitryx.brkmopt.CenarioController.getCenarioJson(CenarioController.groovy:20)
        at org.grails.core.DefaultGrailsControllerClass$MethodHandleInvoker.invoke(DefaultGrailsControllerClass.java:223)
        at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188)
        at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
        ... 18 common frames omitted

【问题讨论】:

  • tomcat 拾取并提供给所有 web 应用程序的文件已配置 - 所以一个简单的副本可能足够也可能不够。其次,从 clojure 1.9 开始,clojure.jar 还依赖于 spec-alpha 和 core-specs-alpha jars。如果是这种情况,您的 stracktrace 应该会告诉您,但我提到它以防万一。从长远来看,您最好将 clojure 依赖添加到您的 grails 项目中?
  • 感谢您的见解!我们在 grails 项目中添加了所有 Clojure 依赖项。它在一台服务器(B)中运行良好。已经运行了几个月。新服务器(A)运行保存WAR文件时抛出异常。
  • 其他要探索的事情:检查两个服务器中的 CLASSPATH 环境变量。 WAR 可能包含无效的 JAR,并且 Clojure 类在其他地方找到(Tomcat 自己的 JAR 或 JDK 本身的 lib 文件夹中的额外 JAR)。另外,尝试在新的 Ubuntu 服务器中重现,看看差异是否可以归因于操作系统设置或 Tomcat 设置的差异。
  • 我们遇到了某种类似的问题,但是第 3 方库在服务器上抛出 NoSuchMethodError,同时在本地机器上愉快地工作。原来这是一个依赖冲突——即同一个库的多个版本包含在类路径中,但与在本地运行时相比,在远程服务器上运行时选择了不同的版本。检查您的类路径是否存在冲突,可能使用lein deps :tree
  • 好电话!我们会尽快检查!并会通知您。

标签: clojure ubuntu-16.04 tomcat8 suse clojure-java-interop


【解决方案1】:

看起来 Tomcat 8.5.50 在 Catalina 中包含一堆回归修复,这些修复可能会影响 Clojure 源文件的加载。建议降级到与工作版本相同或升级到 8.5.50。

https://tomcat.apache.org/tomcat-8.5-doc/changelog.html

【讨论】:

    猜你喜欢
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多