I've got the following directory structure in tomcat 6:
tomcat
|-lib
| |- logback-classic.jar
| |- logback-core.jar
| |- slf4j-api.jar
| |- myState.jar
|-shared
| |-lib
| | |- myStateLogback.xml
|-webapps
| |-myApp
| | |-WEB-INF
| | | |-logback.xml
| | | |-lib
| | | | |-jcl-over-slf4j.jar
| | | | |-logback-classic.jar
| | | | |-logback-core.jar
| | | | |-slf4j-api.jar
myState.jar needs to live in the tomcat/lib directory as it is contains classes needed on tomcat startup as a global resource. It writes it's logging to slf4j so also needs the slf4j and logback jars. It uses a JoranConfigurator to load myStateLogback.xml.
myApp webapp writes it's logging to commons-logging, but I want it go through slf4j to logback in preparation for moving all our logging to slf4j, so I'm using the jcl-over-slf4j bridge.
With the above setup, the logging all works, but I get the following warning on startup:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/tomcat/lib/logback-classic-0.9.29.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/tomcat/webapps/myApp/WEB-INF/lib/logback-classic-0.9.29.jar!/org/slf4j/impl/StaticLoggerBinder.class]
If I take logback-classic out of the webapp's lib dir, I get the following exception:
Exception in thread "Timer-30" java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/apache/catalina/loader/WebappClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of org/apache/catalina/loader/StandardClassLoader) for resolved class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:284)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:252)
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:272)
If I remove the 2 logback jars, and the slf4j-api.jar from the webapp's lib directory, I get no warnings and no exceptions, but the logs from my webapp are picked up by the myStateLogback.xml file and go to it's logger, which I don't want. I know I can filter out the statements I don't want, but I want to have separate config files for the webapp and the jar. Is there a way to achieve this?
I'm using tomcat 6.0.23, logback 0.9.29 and slf4j 1.6.3.
Thanks, Sarah
If you are looking for quick solution for this issue, you need to find out how log4j is present on your path. run mvn dependency:tree and figure out the maven dependency and exclude log4j with snippet below to that dependency in your pom. xml . This should resolve SLF4J: Class Path Contains Multiple SLF4J Bindings.
Bindings are basically implementations of a particular SLF4J class meant to be extended to plug in a specific logging framework. By design, SLF4J will only bind with one logging framework at a time. Consequently, if more than one binding is present on the classpath, it will emit a warning.
SLF4J supports popular logging frameworks, namely log4j, java. util. logging, Simple logging and NOP. The logback project supports SLF4J natively.
This error indicates that appropriate SLF4J binding could not be found on the class path. Placing one (and only one) of slf4j-nop. jar, slf4j-simple. jar, slf4j-log4j12. jar, slf4j-jdk14.
There is a chapter entitled logging separation in the logback documentaiton which presents one possible solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With