22

I am getting the error

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/george/.gradle/caches/artifacts-26/filestore/org.apache.logging.log4j/log4j-slf4j-impl/2.0-beta8/jar/15984318e95b9b0394e979e413a4a14f322401c1/log4j-slf4j-impl-2.0-beta8.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/george/.gradle/caches/artifacts-26/filestore/org.slf4j/slf4j-log4j12/1.5.0/jar/aad1074d37a63f19fafedd272dc7830f0f41a977/slf4j-log4j12-1.5.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.

In my build.gradle file I have the following line to include the jar log4j-slf4j-impl-2.0-beta8.jar (which I want to bind to LOG4J2)

 compile 'org.apache.logging.log4j:log4j-slf4j-impl:2.0-beta8' 

In another build.gradle file in a dependent project I have multiple lines similar to the following:

 compile 'dcm4che:dcm4che-core:2.0.23'

Now dcm4che includes a dependency on log4j version 1 (slf4j-log4j12) and this is therefore being included in the overall project.

Here is a snippet from the Gradle dependency tree:

|    +--- dcm4che:dcm4che-core:2.0.23
|    |    \--- org.slf4j:slf4j-log4j12:1.5.0
|    |         +--- org.slf4j:slf4j-api:1.5.0 -> 1.7.5
|    |         \--- log4j:log4j:1.2.13 -> 1.2.14

I have read the link suggested in the warning but I cannnot figure out how to make my app bind to log4j2 using the jar that I want. The Gradle documentation on dependency management has not really made it any clearer.

giorgio
  • 2,115
  • 5
  • 23
  • 39

3 Answers3

29

Put this code in your build.gradle file

configurations.all {
   exclude group: 'org.slf4j', module: 'slf4j-log4j12'
}
Quy Tang
  • 3,929
  • 1
  • 31
  • 45
16

The solution is to add the following in the build.gradle.

configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        if (details.requested.name == 'log4j') {
            details.useTarget "org.slf4j:log4j-over-slf4j:1.7.5"
        }
}

The result is that anything that normally requires log4j will use log4j-over-slf4j instead.

I also added:

if (details.requested.name == 'commons-logging') {
    details.useTarget "org.slf4j:jcl-over-slf4j:1.7.5"
}

for completeness to cover commons logging.

giorgio
  • 2,115
  • 5
  • 23
  • 39
8

Exclude the dependency that contain the slf4j .jar you do not want to use. For gradle this may help in doing so.

update:

Unfortunately I am not familiar with gradle, but judging from the linked documentation sth. like

compile('dcm4che:dcm4che-core:2.0.23') {
   exclude group: 'org.slf4j'
}

may work? Note that the documentation mentions a sort of 'configuration-global' exclusion list, which may be a better way to do this, but I failed to find more information on that.

Pyranja
  • 3,529
  • 22
  • 24
  • Yes that is indeed exactly what I want to do. I am just unable to figure out from the Gradle documentation how exactly to do this. – giorgio Sep 23 '13 at 09:51