How to suppress SLF4J Warning about multiple bindings?

Have you read the URL referenced by the warning?

SLF4J: See [http://www.slf4j.org/codes.html#multiple_bindings][1] for an explanation.

Here is what the link states:

SLF4J API is desinged to bind with one and only one underlying logging framework at a time. If more than one binding is present on the class path, SLF4J will emit a warning, listing the location of those bindings. When this happens, select the one and only one binding you wish to use, and remove the other bindings.

For example, if you have both slf4j-simple-1.6.2.jar and slf4j-nop-1.6.2.jar on the class path and you wish to use the nop (no-operation) binding, then remove slf4j-simple-1.6.2.jar from the class path.

Note that the warning emitted by SLF4J is just that, a warning. SLF4J will still bind with the first framework it finds on the class path.


Remove one of the slf4j-log4j12-1.5.8.jar or slf4j-log4j12-1.6.0.jar from the classpath. Your project should not depend on different versions of SLF4J. I suggest you to use just the 1.6.0.

If you're using Maven, you can exclude transitive dependencies. Here is an example:

<dependency>
    <groupId>com.sun.xml.stream</groupId>
    <artifactId>sjsxp</artifactId>
    <version>1.0.1</version>
    <exclusions>
        <exclusion>
            <groupId>javax.xml.stream</groupId>
            <artifactId>stax-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

With the current slf4j-api implementation it is not possible to remove these warnings. The org.slf4j.LoggerFactory class prints the messages:

  ...
  if (implementationSet.size() > 1) {
    Util.report("Class path contains multiple SLF4J bindings.");
    Iterator iterator = implementationSet.iterator();
    while(iterator.hasNext()) {
      URL path = (URL) iterator.next();
      Util.report("Found binding in [" + path + "]");
    }
    Util.report("See " + MULTIPLE_BINDINGS_URL + " for an explanation.");
  }
  ...

The Util class is the following:

public class Util {

  static final public void report(String msg, Throwable t) {
    System.err.println(msg);
    System.err.println("Reported exception:");
    t.printStackTrace();
  }
  ...

The report method writes directly to System.err. A workaround could be to replace the System.err with System.setErr() before the first LoggerFactory.getLogger() call but you could lose other important messages if you do that.

Of course you can download the source and remove these Util.report calls and use your modified slf4j-api in your project.


    PrintStream filterOut = new PrintStream(System.err) {
        public void println(String l) {
            if (! l.startsWith("SLF4J")) {
                super.println(l);
            }
        }
    };
    System.setErr(filterOut);

et voilà!