简体   繁体   中英

How can I prevent SLF4J's infamous “multiple bindings” warning at build time?

My program outputs the following annoying message:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/scratch/events-beware/events-beware/build/install/events-beware/lib/logback-classic-1.1.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/scratch/events-beware/events-beware/build/install/events-beware/lib/slf4j-log4j12-1.6.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/scratch/events-beware/events-beware/build/install/events-beware/lib/slf4j-simple-1.6.1.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]

The unwanted SLF4J bindings are transitive dependencies of my project, so I configure my dependency manager to exclude the jars containing the unwanted bindings. This works for a while, until a new dependency is added to the project, which pulls in yet another unwanted binding...

How can I use the power of my build system to fail the build if I transitively depend on multiple SLF4J bindings?

At build time you can check each of your dependencies, looking for an SLF4J binding. If you find more than one, you can fail the build.

To do this with Gradle:

task checkSlf4j {
    description 'Ensure only one SFL4j binding is present in the runtime configuration'

    doLast {
        def bindings = []
        configurations.runtime.each {
            zipTree(it).matching { include 'org/slf4j/impl/StaticLoggerBinder.class' }.each { c ->
                bindings << [it.getName(), c]
            }
        }
        if (bindings.size () > 1) {
            throw new GradleException("Multiple SLF4J bindings found: ${bindings*.getAt(0)}")
        }
    }
}

check.dependsOn checkSlf4j

Here's the result:

$ ./gradlew build
:bundleJars UP-TO-DATE
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:assemble UP-TO-DATE
:checkSlf4j FAILED

FAILURE: Build failed with an exception.

* Where:
Script '/scratch/events-beware/events-beware/slf4j.gradle' line: 14

* What went wrong:
Execution failed for task ':checkSlf4j'.
> Multiple SLF4J bindings found: [logback-classic-1.1.2.jar, slf4j-log4j12-1.6.1.jar, slf4j-simple-1.6.1.jar]

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 2.009 secs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM