36

I can't figure it out where a binding collision is. I have my Spring Boot 1.2.6.RELEASE service and I'm getting this error when I run it:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/jscherman/.m2/repository/ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/jscherman/.m2/repository/org/slf4j/slf4j-log4j12/1.7.12/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]

This is the mvn dependency:tree output

[INFO] com.myenterprise:product-manager:jar:0.0.1-SNAPSHOT
[INFO] +- com.myenterprise.product:myproject-api:jar:0.0.1-SNAPSHOT:compile
[INFO] +- com.myenterprise.product:myproject-core:jar:0.0.1-SNAPSHOT:compile
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:1.2.6.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:1.2.6.RELEASE:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:8.0.26:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:8.0.26:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-logging-juli:jar:8.0.26:compile
[INFO] |  |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:8.0.26:compile
[INFO] |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.4.6:compile
[INFO] |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.4.6:compile
[INFO] |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.4.6:compile
[INFO] |  +- org.hibernate:hibernate-validator:jar:5.1.3.Final:compile
[INFO] |  |  +- javax.validation:validation-api:jar:1.1.0.Final:compile
[INFO] |  |  +- org.jboss.logging:jboss-logging:jar:3.1.3.GA:compile
[INFO] |  |  \- com.fasterxml:classmate:jar:1.0.0:compile
[INFO] |  +- org.springframework:spring-core:jar:4.1.7.RELEASE:compile
[INFO] |  +- org.springframework:spring-web:jar:4.1.7.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-aop:jar:4.1.7.RELEASE:compile
[INFO] |  \- org.springframework:spring-webmvc:jar:4.1.7.RELEASE:compile
[INFO] |     \- org.springframework:spring-expression:jar:4.1.7.RELEASE:compile
[INFO] +- org.springframework.boot:spring-boot-starter-data-jpa:jar:1.2.6.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-aop:jar:1.2.6.RELEASE:compile
[INFO] |  |  +- org.aspectj:aspectjrt:jar:1.8.6:compile
[INFO] |  |  \- org.aspectj:aspectjweaver:jar:1.8.6:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-jdbc:jar:1.2.6.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-jdbc:jar:4.1.7.RELEASE:compile
[INFO] |  |  +- org.apache.tomcat:tomcat-jdbc:jar:8.0.26:compile
[INFO] |  |  |  \- org.apache.tomcat:tomcat-juli:jar:8.0.26:compile
[INFO] |  |  \- org.springframework:spring-tx:jar:4.1.7.RELEASE:compile
[INFO] |  +- org.hibernate:hibernate-entitymanager:jar:4.3.11.Final:compile
[INFO] |  |  +- org.jboss.logging:jboss-logging-annotations:jar:1.2.0.Beta1:compile
[INFO] |  |  +- org.hibernate:hibernate-core:jar:4.3.11.Final:compile
[INFO] |  |  |  +- antlr:antlr:jar:2.7.7:compile
[INFO] |  |  |  \- org.jboss:jandex:jar:1.1.0.Final:compile
[INFO] |  |  +- dom4j:dom4j:jar:1.6.1:compile
[INFO] |  |  |  \- xml-apis:xml-apis:jar:1.0.b2:compile
[INFO] |  |  +- org.hibernate.common:hibernate-commons-annotations:jar:4.0.5.Final:compile
[INFO] |  |  +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile
[INFO] |  |  \- org.javassist:javassist:jar:3.18.1-GA:compile
[INFO] |  +- javax.transaction:javax.transaction-api:jar:1.2:compile
[INFO] |  +- org.springframework:spring-orm:jar:4.1.7.RELEASE:compile
[INFO] |  +- org.springframework.data:spring-data-jpa:jar:1.7.3.RELEASE:compile
[INFO] |  |  +- org.springframework.data:spring-data-commons:jar:1.9.3.RELEASE:compile
[INFO] |  |  \- org.slf4j:slf4j-api:jar:1.7.12:compile
[INFO] |  \- org.springframework:spring-aspects:jar:4.1.7.RELEASE:compile
[INFO] +- mysql:mysql-connector-java:jar:5.1.36:compile
[INFO] +- org.flywaydb:flyway-core:jar:3.1:compile
[INFO] +- org.springframework.security.oauth:spring-security-oauth2:jar:2.0.7.RELEASE:compile
[INFO] |  +- org.springframework:spring-beans:jar:4.1.7.RELEASE:compile
[INFO] |  +- org.springframework:spring-context:jar:4.1.7.RELEASE:compile
[INFO] |  +- org.springframework.security:spring-security-core:jar:3.2.8.RELEASE:compile
[INFO] |  |  \- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  +- org.springframework.security:spring-security-config:jar:3.2.8.RELEASE:compile
[INFO] |  +- org.springframework.security:spring-security-web:jar:3.2.8.RELEASE:compile
[INFO] |  +- commons-codec:commons-codec:jar:1.6:compile
[INFO] |  \- org.codehaus.jackson:jackson-mapper-asl:jar:1.9.13:compile
[INFO] |     \- org.codehaus.jackson:jackson-core-asl:jar:1.9.13:compile
[INFO] +- org.springframework.boot:spring-boot-starter:jar:1.2.6.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot:jar:1.2.6.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-autoconfigure:jar:1.2.6.RELEASE:compile
[INFO] |  \- org.yaml:snakeyaml:jar:1.14:compile
[INFO] +- org.springframework.boot:spring-boot-starter-log4j:jar:1.2.6.RELEASE:compile
[INFO] |  +- org.slf4j:jcl-over-slf4j:jar:1.7.12:compile
[INFO] |  +- org.slf4j:jul-to-slf4j:jar:1.7.12:compile
[INFO] |  +- org.slf4j:slf4j-log4j12:jar:1.7.12:compile
[INFO] |  \- log4j:log4j:jar:1.2.17:compile
[INFO] \- org.springframework.boot:spring-boot-starter-test:jar:1.2.6.RELEASE:compile
[INFO]    +- junit:junit:jar:4.12:compile
[INFO]    +- org.mockito:mockito-core:jar:1.10.19:compile
[INFO]    |  \- org.objenesis:objenesis:jar:2.1:runtime
[INFO]    +- org.hamcrest:hamcrest-core:jar:1.3:compile
[INFO]    +- org.hamcrest:hamcrest-library:jar:1.3:compile
[INFO]    \- org.springframework:spring-test:jar:4.1.7.RELEASE:compile

So, apparently the problem is that logback is still in the classpath, but I couldn't find it in the output so I don't know where the problem is.

Note: This only happens when I run the server as a Spring Boot Application. If I run it as a Java application, the error is gone.

Can you spot the error?

M. Justin
  • 14,487
  • 7
  • 91
  • 130
jscherman
  • 5,839
  • 14
  • 46
  • 88

10 Answers10

34

I had the exact same problem and could only see the dependency coming from spring boot. It also brought in log4j-over-slf4j, which clashed with my own requirement of slf4j-log4j12. Solved by adding the exclusions below. This is more specific that excluding the spring boot logging.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>logback-classic</artifactId>
            <groupId>ch.qos.logback</groupId>
        </exclusion>
        <exclusion>
            <artifactId>log4j-over-slf4j</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
    </exclusions>
</dependency>
Stephen
  • 743
  • 7
  • 18
  • 2
    if I do this I get a new 'error': log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. If I ommit the log4j-over-slf4j from the exclusion list I get: SLF4J: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError. SLF4J: See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details. – R. Sluiter Dec 23 '17 at 12:27
  • I get the same behaviour, if I exclude as above then log4j is not initialised. If I don't exclude I get the class path error. – Jim Jul 07 '19 at 06:57
  • For maven mvn surefire plugin [exclude separatey](/q/12053316) using a `classpathDependencyExclude`. Results in ` org.springframework.boot:spring-boot-starter-logging ` – cachius Jan 25 '23 at 13:19
7

Since all earlier answers haven't been successful to get log4j2 working (at least not for me), I found the solution at https://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html#howto-configure-log4j-for-logging. Basically, exclude org.springframework.boot:spring-boot-starter-logging from org.springframework.boot:spring-boot-starter and add org.springframework.boot:spring-boot-starter-log4j2 as dependency in your pom.xml.

SaschaH
  • 351
  • 3
  • 10
6

When want to use log4j for logging, and exclude default logback implementation, add this dependency if not already there, or add the exclusion clause.

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter</artifactId>
 <exclusions>
     <exclusion>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-logging</artifactId>
     </exclusion>
 </exclusions>
</dependency>

Refer Spring Logging - How To.

TechFree
  • 2,600
  • 1
  • 17
  • 18
5

Remove the dependency on spring-boot-starter-log4j which is bringing in slf4j-log4j12, I think you should use use log4j-over-slf4j if you have some code that depends on log4j. See here for a distinction.

David Roussel
  • 5,788
  • 1
  • 30
  • 35
  • this solved the problem if i run it as Spring Boot App, but fails if i run it as Java Application (contrary as what were happening at the beginning). Any ideas? thanks – jscherman Oct 12 '15 at 22:52
  • What is the difference between the two launching methods? – David Roussel Oct 13 '15 at 12:25
  • As it is documented on [doc](https://spring.io/blog/2015/03/18/spring-boot-support-in-spring-tool-suite-3-6-4#running-a-boot-app-in-sts), apparently when running an app as Spring Boot App it adds some stuff – jscherman Oct 14 '15 at 01:14
  • 1
    I have used spring-boot, but I don't have a running example here. So I'm not sure how I can help further. I would suggest finding the code in spring boot that sets up the loggers, and check if it's being called in both launch modes. – David Roussel Oct 14 '15 at 08:11
3

You using logback.xml on your classpath & have spring-boot-starter-log4j:jar on your pom thats why the conflict for which StaticLoggerBinder to use.

SLF4J: Found binding in [jar:file:/home/jscherman/.m2/repository/ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/jscherman/.m2/repository/org/slf4j/slf4j-log4j12/1.7.12/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]

Pls remove either one of the logging library, say spring-boot-starter-log4j from your pom to remove the conflict.

Avis
  • 2,197
  • 18
  • 28
3

Maven Helper plug-in is super helpful in quickly visualizing the dependency graph and identifying the conflicts and resolving them inline with a simple click.

  • 1
    Your answer is not really an answer to the question. I think it would be a good comment, because it may help jscherman to go into the right direction. – Jochen Haßfurter Oct 13 '20 at 20:28
  • +1 Very nice Plugin. Been using IntelliJ for years and didn't knew this. Although it didn't find my conflicting imports in "Conflicts", I managed to find the roots of the conflicting imports with the dependecy-lists. – JackLeEmmerdeur Nov 14 '20 at 21:32
2

This error is caused by there are more than one SLF4J implementation in class path . SLF4J is an abstraction for various logging frameworks(such as log4j or logback) ,which detects the implementation during compile phase by static method .

From your dependency:tree , I only find log4j ,there is no logback related jar

[INFO] +- org.springframework.boot:spring-boot-starter-log4j:jar:1.2.6.RELEASE:compile
[INFO] |  +- org.slf4j:jcl-over-slf4j:jar:1.7.12:compile
[INFO] |  +- org.slf4j:jul-to-slf4j:jar:1.7.12:compile
[INFO] |  +- org.slf4j:slf4j-log4j12:jar:1.7.12:compile
[INFO] |  \- log4j:log4j:jar:1.2.17:compile

You should try to run maven - update project firstly , and check it again .

JZH
  • 47
  • 2
2

All the above answers on this page are correct and point to the same direction, but the procedure is quite challenging and cumbersome.

I highly advise to use or take help of a standard plugin e.g. Maven helper plugin

Himadri Mandal
  • 325
  • 2
  • 11
1

Posting this if anyone else faces the same issue in the future.

In large projects, there will be multiple dependencies, and putting an exclusion in one or two of them might not always work. In my case also I was not able to find logback-classic in the dependency tree of the project which I'm trying to run. For me, the reason was

  • There were other internal projects that were included in Build Path. Those projects were using the logback-classic.

Solution:

  • First step is to know what is actually required in your project, i.e. logback-classic or slf4j-api
  • To begin with, you can start putting exclusions of slf4j-api in dependencies.
  • If you start to get any compilation errors, then slf4-api is required and you just have to repeat the same process for logback-classic until it's completely gone from the dependency tree and other internal projects.
  • In case, you do not get any compilation errors, you will have to keep excluding slf4j-api from dependencies.
  • If internal projects are also included in build path, might have to repeat the process for those projects as well
Akki
  • 754
  • 7
  • 22
0

If you are using kubernetes and want to fix this quickly (for testing purpose for example), you can use this as a workaround in your kuberenetes deployment:

      volumeMounts:
        - name: slf4j-exclude
          mountPath: /exclude
          readOnly: true
  volumes:
    - name: slf4j-exclude
      emptyDir: {}
Bguess
  • 1,700
  • 1
  • 11
  • 24