Reputation: 13716
I've gotten the famous SLF4J class name collision error with sbt-assembly (below). The docs do say that SLF4J is pathological in this regard, in some way which is kept a little vague. Anyway, this happens in a project having a lot of dependencies, and it remains unclear how should one figure which classes can be just thrown away to avoid the collision without crashing at runtime.
[error] (project-name/*:assembly) deduplicate: different file contents found in the following:
[error] .ivy2/cache/commons-logging/commons-logging/jars/commons-logging-1.2.jar:org/apache/commons/logging/Log.class
[error] .ivy2/cache/org.slf4j/jcl-over-slf4j/jars/jcl-over-slf4j-1.7.12.jar:org/apache/commons/logging/Log.class
[error] deduplicate: different file contents found in the following:
[error] .ivy2/cache/commons-logging/commons-logging/jars/commons-logging-1.2.jar:org/apache/commons/logging/LogConfigurationException.class
[error] .ivy2/cache/org.slf4j/jcl-over-slf4j/jars/jcl-over-slf4j-1.7.12.jar:org/apache/commons/logging/LogConfigurationException.class
[error] deduplicate: different file contents found in the following:
[error] .ivy2/cache/commons-logging/commons-logging/jars/commons-logging-1.2.jar:org/apache/commons/logging/LogFactory.class
[error] .ivy2/cache/org.slf4j/jcl-over-slf4j/jars/jcl-over-slf4j-1.7.12.jar:org/apache/commons/logging/LogFactory.class
[error] deduplicate: different file contents found in the following:
[error] .ivy2/cache/commons-logging/commons-logging/jars/commons-logging-1.2.jar:org/apache/commons/logging/impl/NoOpLog.class
[error] .ivy2/cache/org.slf4j/jcl-over-slf4j/jars/jcl-over-slf4j-1.7.12.jar:org/apache/commons/logging/impl/NoOpLog.class
[error] deduplicate: different file contents found in the following:
[error] .ivy2/cache/commons-logging/commons-logging/jars/commons-logging-1.2.jar:org/apache/commons/logging/impl/SimpleLog$1.class
[error] .ivy2/cache/org.slf4j/jcl-over-slf4j/jars/jcl-over-slf4j-1.7.12.jar:org/apache/commons/logging/impl/SimpleLog$1.class
[error] deduplicate: different file contents found in the following:
[error] .ivy2/cache/commons-logging/commons-logging/jars/commons-logging-1.2.jar:org/apache/commons/logging/impl/SimpleLog.class
[error] .ivy2/cache/org.slf4j/jcl-over-slf4j/jars/jcl-over-slf4j-1.7.12.jar:org/apache/commons/logging/impl/SimpleLog.class
[error] deduplicate: different file contents found in the following:
[error] .ivy2/cache/ch.qos.logback/logback-classic/jars/logback-classic-1.1.3.jar:org/slf4j/impl/StaticLoggerBinder.class
[error] .ivy2/cache/org.slf4j/slf4j-nop/jars/slf4j-nop-1.6.4.jar:org/slf4j/impl/StaticLoggerBinder.class
[error] deduplicate: different file contents found in the following:
[error] .ivy2/cache/ch.qos.logback/logback-classic/jars/logback-classic-1.1.3.jar:org/slf4j/impl/StaticMDCBinder.class
[error] .ivy2/cache/org.slf4j/slf4j-nop/jars/slf4j-nop-1.6.4.jar:org/slf4j/impl/StaticMDCBinder.class
[error] deduplicate: different file contents found in the following:
[error] .ivy2/cache/ch.qos.logback/logback-classic/jars/logback-classic-1.1.3.jar:org/slf4j/impl/StaticMarkerBinder.class
[error] .ivy2/cache/org.slf4j/slf4j-nop/jars/slf4j-nop-1.6.4.jar:org/slf4j/impl/StaticMarkerBinder.class
What might be the methodology for untangling this awful mess? and I really wonder, why in fact, is this an issue in packaging (sbt assembly
), and not when running the project in sbt as in sbt run
?
Many thanks!
Upvotes: 2
Views: 1074
Reputation: 95654
Have you read the actual link to Bridging legacy APIs from the README.md?:
Gradual migration to SLF4J from Jakarta Commons Logging (JCL)
jcl-over-slf4j.jar
To ease migration to SLF4J from JCL, SLF4J distributions include the jar file jcl-over-slf4j.jar. This jar file is intended as a drop-in replacement for JCL version 1.1.1. It implements the public API of JCL but using SLF4J underneath, hence the name "JCL over SLF4J."
Our JCL over SLF4J implementation will allow you to migrate to SLF4J gradually, especially if some of the libraries your software depends on continue to use JCL for the foreseeable future.
jcl-over-slf4j.jar
"is intended as a drop-in replacement for JCL version 1.1.1." So the intended purpose it is to remove the Commons Logging proper.
What might be the methodology for untangling this awful mess?
Run show update
, find out where commons-logging is coming from, and exclude it from your dependencies.
and I really wonder, why in fact, is this an issue in packaging (
sbt assembly
), and not when running the project in sbt as insbt run
?
It's an actual pathological classpath. In terms of logging, some part of your code could be doing something completely unexpected to what was intended. If you want to go for the Russian roulette route, there's always MergeStrategy.first
.
Upvotes: 3