Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tomcat ClassNotFoundException: org.slf4j.spi.LoggerFactoryBinder but slf4j is in libs

I keep getting the following error:

Failed to instantiate SLF4J LoggerFactory
Reported exception:
java.lang.NoClassDefFoundError: org/slf4j/spi/LoggerFactoryBinder
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:270)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1562)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1420)
        at org.slf4j.LoggerFactory.bind(LoggerFactory.java:129)
        at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:108)
        at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:302)
        at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:276)
        at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:156)
        at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:132)
        at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:274)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:282)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4830)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5276)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:726)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:702)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:698)
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:968)
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1742)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.ClassNotFoundException: org.slf4j.spi.LoggerFactoryBinder
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        ... 37 more
21-Jun-2014 17:06:51.352 SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.startInternal Error listenerStart
21-Jun-2014 17:06:51.358 SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.startInternal Context [/spring-app] startup failed due to previous errors
21-Jun-2014 17:06:51.399 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory /media/win/d/coding/servers/tomcat/apache-tomcat-8.0.0-RC5/webapps/docs
21-Jun-2014 17:06:51.829 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory /media/win/d/coding/servers/tomcat/apache-tomcat-8.0.0-RC5/webapps/examples
21-Jun-2014 17:06:53.181 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory /media/win/d/coding/servers/tomcat/apache-tomcat-8.0.0-RC5/webapps/host-manager
21-Jun-2014 17:06:53.575 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory /media/win/d/coding/servers/tomcat/apache-tomcat-8.0.0-RC5/webapps/manager
21-Jun-2014 17:06:53.950 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory /media/win/d/coding/servers/tomcat/apache-tomcat-8.0.0-RC5/webapps/ROOT
21-Jun-2014 17:06:54.324 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
21-Jun-2014 17:06:54.328 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
21-Jun-2014 17:06:54.329 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 9393 ms
21-Jun-2014 17:07:14.840 INFO [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.startup.HostConfig.undeploy Undeploying context [/spring-app]
21-Jun-2014 17:07:44.907 INFO [localhost-startStop-2] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive /media/win/d/coding/servers/tomcat/apache-tomcat-8.0.0-RC5/webapps/spring-app.war
Failed to instantiate SLF4J LoggerFactory
Reported exception:
java.lang.NoClassDefFoundError: org/slf4j/spi/LoggerFactoryBinder
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:270)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1562)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1420)
        at org.slf4j.LoggerFactory.bind(LoggerFactory.java:129)
        at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:108)
        at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:302)
        at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:276)
        at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:156)
        at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:132)
        at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:274)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:282)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4830)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5276)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:726)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:702)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:698)
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:968)
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1742)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.ClassNotFoundException: org.slf4j.spi.LoggerFactoryBinder
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        ... 37 more

It makes no sense because I DO have org.slf4j.spi.LoggerFactoryBinder in web-app/WEB-INF/lib/slf4j-api-1.7.6.jar and this worked also yesterday but suddenly the web app cannot be started.

What can be causing this?
How can I check/debug the classpath for a web application in Tomcat at the start?

like image 647
ps-aux Avatar asked Jun 21 '14 15:06

ps-aux


2 Answers

You say that the slf4j API jar is (was) part of the web application. I'm guessing that your slf4j binding jar is (was) installed in Tomcat's lib directory or some such place where it wasn't private to the web application. This seems like it ought to be a natural way to use Slf4j--the web app brings with it the API jar, and the tomcat installation provides the correct binding. Unfortunately, this doesn't work.

Refer to the Tomcat classloader how-to. When Slf4j is deployed in this fashion, the API jar is loaded using the private classloader for the web app, while the binding jar is loaded using the "common" classloader or one of the other general classloaders. Classes in the webapp classloader can load classes from the common loader, but classes in the common loader can't access the webapp loader.

Specifically, your exception occurs when a class in the API jar is trying to load a class in the binding jar, namely org.slf4j.impl.StaticLoggerBinder. Your code in the web app is able to access the API jar, and the API jar is able to find this class in the binding jar. But, StaticLoggingBinder references org.slf4j.spi.LoggerFactoryBinder which is back in the API jar. Classes in the binding jar can't access the webapp classloader, so it's not able to load the class and you get the exception.

Unfortunately, the only straightforward solution is to deploy both the Slf4j API and binding jars in the same "place". They should both be part of the web app's private classes, or else both part of the common Tomcat classes.

like image 115
Kenster Avatar answered Nov 01 '22 05:11

Kenster


If you're running Tomcat with the catalina.sh (or .bat) scripts -which are used by startup.sh and shutdown.sh), then you could modify the JAVA_OPTS variable to include the "-verbose:class" switch. That will cause information of classes loaded to be printed to standard out

Regarding your issue, I have a feeling that there may be some older version of jar which may be conflicting

like image 1
vinayknl Avatar answered Nov 01 '22 05:11

vinayknl