7
votes

I have a third party dependency in my play project. That third party library has eventual dependency ( not direct ) on an slf4j implementation.

I am getting duplicate binding error for slf4j.

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:~/.ivy2/cache/ch.qos.logback/logback-classic/jars/logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/~/.ivy2/cache/com.orgname.platform/platform-logging-client/jars/platform-logging-client-2.5.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]

I tried following things but can get rid of the error.

"com.orgname.platform" % "platform-metric-client" % "1.0.4" excludeAll(
    ExclusionRule(organization = "org.slf4j"))

I also tried following exclusion

"com.orgname.platform" % "platform-metric-client" % "1.0.4" exclude("org.slf4j","slf4j-jdk14)

and also this one

 "com.orgname.platform" % "platform-metric-client" % "1.0.4" exclude("org.slf4j","slf4j-log4j12)

Since I was not able to remove the slf4j from third party dependency I, tired to remove the play dependency on slf4j, by modifying projcts/plugin.sbt

addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.4.6" exclude("org.slf4j", "slf4j-simple"))

How should I go about getting rid of this warning. how does this warning impact the logging? Which logging implementation would be used the Scala implementation?

4

4 Answers

7
votes

The answer by YourBestBet is correct, but you can save yourself some copy-pasting by mapping the sequence of imports with the excludes.

//dependencies with exclusions
libraryDependencies ++= Seq(
    //depencies
).map(_.exclude("org.slf4j", "*"))

//insert one without exclusion
libraryDependencies ++= Seq(
  "ch.qos.logback" % "logback-classic" % "1.1.3"
)

EDIT:

I suggest investing some time and understanding transitive dependencies and scope management. It will save you time in the future. Maven has a great and straightforward doc page about it: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

PS. Exclude? Provided?

3
votes

IMHO, No matter exclude or excludeAll , it only excludes slf4j dependency from THAT library, not excluding slf4j dependency from the whole project. Thus, all library dependencies lines which may transitively depend on slf4j need to add exclude("org.slf4j","slf4j-log4j12).

A quick and dirty solution is to append exclude("org.slf4j","slf4j-log4j12) to each libraryDepencies line. I tried this, it worked for me.

1
votes

Both answers provided by @YourBestBet and @goozez are correct if your goal is to exclude the dependency from the project.

In my project , I had multiple dependencies that included slf4j and they conflicted with each other.

An easy fix (but tedious depending on the number of dependencies you have) is to exclude it from the conflicting dependency manually instead of removing it entirely from the project as you might need it.

  "org.elasticsearch" % "elasticsearch" % esVersion exclude("org.slf4j", "*"),
0
votes

Tell SBT that SLF4J is provided and SBT won't add it to the classpath. To do that, add the following to libraryDependencies:

"org.slf4j" % "slf4j-simple" % "1," Provided

It is possible that various dependencies (or their transitive dependencies) might reference SLF4J with varying versions. That is why I used an Ivy version range matcher. You might find that the actual version matcher you need is some variation of what I wrote.