Slf4j library transitive dependency nightmare

@drse / updated May 12, 2015

Share:  

Let's say you have a java/groovy library that uses slf4j.

If you want to compile the dependency into the lib as a fat jar or distributable, you'll need to compile in the API rather than the implementation.

Instead of the impl that you'll want in testing/dev:

compile "org.slf4j:slf4j-simple:1.7.10"

You'll want the api for the distributable:

compile "org.slf4j:slf4j-api:1.7.10"

From: http://www.slf4j.org/codes.html#multiple_bindings

Embedded components such as libraries or frameworks should not declare a dependency on any SLF4J binding but only depend on slf4j-api. When a library declares a compile-time dependency on a SLF4J binding, it imposes that binding on the end-user, thus negating SLF4J's purpose. When you come across an embedded component declaring a compile-time dependency on any SLF4J binding, please take the time to contact the authors of said component/library and kindly ask them to mend their ways.

(Alernatively) you may exclude all the deps that have slf4j. In Gradle:

configurations.all {
  exclude group:"org.slf4j"
}

NOTE: this small mistake in the library can cause hours of trying to configure build systems to exclude all the slf4j dependencies. Likewise, in multi-framework builds, it can be a real nightmare.