当SBT装配发现冲突时,为什么Maven装配工作正常

Ata*_*ais 10 maven-3 maven sbt maven-assembly-plugin sbt-assembly

标题也可能是:
Maven和SBT组装插件之间有什么区别.

我发现这是一个问题,同时将项目从Maven迁移到SBT.

为了描述这个问题,我创建了一个带有依赖关系的示例项目,我发现它的行为有所不同,具体取决于构建工具.

https://github.com/atais/mvn-sbt-assembly


唯一的依赖是(sbt风格)

"com.netflix.astyanax" % "astyanax-cassandra" % "3.9.0",
"org.apache.cassandra" % "cassandra-all" % "3.4",
Run Code Online (Sandbox Code Playgroud)

而我不明白的是,为什么mvn package成功地创造了胖罐,同时sbt assembly给出了冲突:

[error] 39 errors were encountered during merge
[error] java.lang.RuntimeException: deduplicate: different file contents found in the following:
[error] /home/siatkowskim/.ivy2/cache/org.slf4j/jcl-over-slf4j/jars/jcl-over-slf4j-1.7.7.jar:org/apache/commons/logging/<some classes>
[error] /home/siatkowskim/.ivy2/cache/commons-logging/commons-logging/jars/commons-logging-1.1.1.jar:org/apache/commons/logging/<some classes>
...
[error] /home/siatkowskim/.ivy2/cache/com.github.stephenc.high-scale-lib/high-scale-lib/jars/high-scale-lib-1.1.2.jar:org/cliffc/high_scale_lib/<some classes>
[error] /home/siatkowskim/.ivy2/cache/com.boundary/high-scale-lib/jars/high-scale-lib-1.0.6.jar:org/cliffc/high_scale_lib/<some classes>
...
Run Code Online (Sandbox Code Playgroud)

Ata*_*ais 5

延伸到阿列克谢·罗曼诺夫的回答

我还更新了我的项目并提供了详细的解释,所以你可能想查看一下。

遵循建议

您可以通过解压 Maven 生成的 jar 和 SBT 错误消息中的依赖项 jar,然后检查 Maven 使用哪个 .class 文件来验证这种情况。

我比较了fat-jarsmavensbt与产生的

  • MergeStrategy.first,显示了一些额外的文件
  • MergeStrategy.last,显示二进制差异和额外文件

我已采取下一步并检查了发现冲突的fat-jars依赖项sbt,具体来说:

结论

maven-assembly-plugin解决jar层面上的冲突。当它发现任何冲突时,它会选择第一个jar并忽略另一个的所有内容。

sbt-assembly混合所有class文件,逐个文件地在本地解决冲突。

我的理论是,如果你fat-jar用作品制作maven-assembly-plugin,你可以MergeStrategy.first指定sbt. 它们唯一的区别是,生成jarsbt会更大,包含被 忽略的额外类maven