logginglog4jslf4jlogback

Force slf4j to use logback


Is there anyway to force slf4j to use specific logging provider (logback in my case)? As in their docs:

Multiple bindings were found on the class path

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 multiple bindings are available on the class path, select one and only one binding you wish to use, and remove the other bindings. For example, if you have both slf4j->simple-1.6.6.jar and slf4j-nop-1.6.6.jar on the class path and you wish to use the nop (>no-operation) binding, then remove slf4j-simple-1.6.6.jar from the class path. If it is not possible to remove the superflous bindings, SLF4J will still bind with one logging framework/implementation. As of version 1.6.6, SLF4J will name the framework/implementation class it is actually bound to.

NOTE The warning emitted by SLF4J is just that, a warning.

In my case i have log4j.jar, slf4j-log4j12.jar, log4j-over-slf4j.jar and all logback jars in classpath. I know that it is error to have slf4j-log4j12.jar and log4j-over-slf4j.jar together, but my project is very big, and it is not always simple to find and exclude maven dependency. In this case slf4j even did not printed any warning, because we use only logback configs. It took me a day to understand this jar hell.

All i want is to force slf4j use logback via JVM argument, for example, so it can print warnings and i can exclude jars in future.


Solution

  • Other than cleaning up your class path, there is no way to force SLF4J to bind with a given implementation.

    Update in 2023: as of SLF4J version 2.0.9, you can specify the provider class explicitly via the "slf4j.provider" system property. This bypasses the service loader mechanism for finding providers and may shorten SLF4J initialization.