SLF4J: java.lang.IllegalStateException: org.slf4j.

2019-08-06 09:20发布

问题:

I have the following maven dependency in my pom file:

<!-- depends on slf4j-api, log4j -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.6.4</version>
</dependency>

When I deploy the project into tomcat, I am getting the error message:

SEVERE: Exception sending context destroyed event to listener instance of class org.springframework.web.context.ContextLoaderListener
java.lang.ExceptionInInitializerError
    at org.springframework.web.context.ContextLoaderListener.contextDestroyed(ContextLoaderListener.java:80)
    at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4819)
    at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5466)
    at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:160)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:895)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:871)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:615)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:958)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1599)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.IllegalStateException: org.slf4j.LoggerFactory could not be successfully initialized. See also http://www.slf4j.org/codes.html#unsuccessfulInit
    at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:288)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:252)
    at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:155)
    at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:131)
    at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:685)
    at org.springframework.web.context.ContextCleanupListener.<clinit>(ContextCleanupListener.java:43)
    ... 16 more

When I look at the deployed war file, I see in the war file the following jars (among others):

slf4j-api-1.6.4.jar
slf4j-log4j12-1.6.4.jar

The strange thing is, that I don't see there any log4j.jar (even though it's a dependency of slf4j-log4j12-1.6.4.jar

Questions:

  1. Why was log4j.jar not packed in the war file?

  2. What does the error message mean and how to solve it?

回答1:

I had this issue due to a bad jar file in the repository. Deleting the entire log4j directory in the Maven repository fixed it once I did Maven > Update Dependencies and it re-downloaded them.



回答2:

The simple thing is, cause you didn't give it as dependency in your pom, cause slf4j is a logging facade which means you have to give the real implementation with it. The error message gives you a hint to the explanation of the cause of this error.



回答3:

I got this error too and I actually had the log4j.jar in my war file. But it turned out to be a classloader issue in my case: I had a jar in my shared/lib which tried to log with slf4j but that classloader did not have the log4j available.



回答4:

It seems as if you need to downgrade your project to slf4j 1.4.2 to work with the log4j available in your tomcat. They are binary incompatible. You would also hang on to the provided afterwards, so you dont include them double.

The alternative is to get the other project to include the libraries themselves and remove from tomcat common. I know of no other exclusion mechanism on the tomcat.

For reference, and probably not helpful, I currently deploy on weblogic and it has a deployment specification that allows one to exclude server common classes and use bundled classes instead, such as the below snippet (with reference)