clojureubuntu-16.04tomcat8suseclojure-java-interop

java.lang.NoClassDefFoundError for clojure.java.api.Clojure


we are struggling here with a java.lang.NoClassDefFoundError that makes no sense.

The same WAR file runs perfectly in the server B, but throws a java.lang.NoClassDefFoundError on server A.

Configurations are:

Server A (throws Exception):

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

Server B (works perfectly):

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

The exception is:

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)
        ...        

The WAR file runs perfectly on server B but throws the exception on server A.

We inspected the ~/WEB-INF/lib/ folder under tomcat, and the necessary dependency (clojure-1.9.0.jar) is there and is consistent. On a desperate action, we have even tried to replace the jar file for a newer one manually, and it did not work.

From Why am I getting a NoClassDefFoundError in Java? :

java.lang.NoClassDefFoundError This exception indicates that the JVM looked in its internal class definition data structure for the definition of a class and did not find it. This is different than saying that it could not be loaded from the classpath. Usually this indicates that we previously attempted to load a class from the classpath, but it failed for some reason

Please advise!

Edit: Full stacktrace: (many thanks to 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

Solution

  • It looks like Tomcat 8.5.50 contains a bunch of regression fixes in Catalina with resource loading which may be affecting the loading of Clojure source files. Suggest either downgrading to same as the working one or upgrading to 8.5.50.

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