In my Vaadin project, I have a dependency on a certain library. This library uses slf4j for logging. In the library pom, logback slf4j binding is added as a runtime dependency.
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope>
</dependency>
In my application, I directly use log4j for logging. I want the logs added by the library to go in my log4j log.
For this, I added following to my pom to include slf4j log4j binding
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
However, slf4j complains that it has found multiple bindings.
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/program_files/apache-tomcat-8.0.24/temp/0-ROOT/WEB-INF/lib/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/program_files/apache-tomcat-8.0.24/temp/0-ROOT/WEB-INF/lib/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
I checked the dependency tree of my application, which has following for its dependency on logback. (Following is the only dependency on logback)
[INFO] | +- com.mycompany.mylib:libname:jar:1.1.0-SNAPSHOT:compile
[INFO] | | +- org.slf4j:jcl-over-slf4j:jar:1.7.5:runtime
[INFO] | | +- ch.qos.logback:logback-classic:jar:1.0.13:runtime
[INFO] | | | \- ch.qos.logback:logback-core:jar:1.0.13:runtime
[INFO] | | +- ch.qos.logback:logback-access:jar:1.0.13:runtime
Also, when I checked inside WEB-INF\lib
directory in my war file, I found following jars.
logback-access-1.0.13.jar
logback-classic-1.0.13.jar
logback-core-1.0.13.jar
Why did logback ended up in my lib directory? As I have heard, runtime dependencies should not come into libs directory.
How should I resolve this? The library is developed within my company and I can ask the library developers to remove the logback runtime dependencies if needed.
Logback does not allow logging to be disabled from the command line. However, if the configuration file allows it, you can set the level of loggers on the command line via a Java system property.
Definitely not deprecated, but logback is generally an improvement, is a stable, mature lib, meshes better with SLF4J (which means no crazy classloader magic), so there's little reason to start a new project with log4j. For the record, Log4J development is deprecated.
Simple Logging Facade for Java (abbreviated SLF4J) acts as a facade for different logging frameworks (e.g., java. util. logging, logback, Log4j). It offers a generic API, making the logging independent of the actual implementation. This allows for different logging frameworks to coexist.
The easiest way to fix this would be to have the library developers in your own company mark logback as optional and require SLF4J as a compile dependency explicitly. This is the right, canonical way to do SLF4J in Maven. In other words:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
If you want to fix it yourself, without going through them, then you can use the exclusions
tag when declaring their dependency. In other words, in your pom, do:
<dependency>
<groupId>your.company</groupId>
<artifactId>libraryname</artifactId>
<version>${theirlibrary.version}</version>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
You asked if there's an reason to depend on Logback directly; generally there isn't, for a library author. Their pom configuration is probably just a minor oversight on their part. There are some reasons to depend on logback specifically, but they have to do with startup (stuff with JoranConfigurator
or StatusPrinter
, that sort of thing, which shouldn't come up with a library. Other reasons to call Logback classes directly include stuff like custom appenders, which, again, shouldn't come up in a library, only a deployed app.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With