我在组装Uber Jar时会出现以下错误:
java.lang.runtimeException:deduplate:找到不同的文件内容 在下面:[错误] /users/jake.stone/.ivy2/cache/org.bouncycastle/bcprov-jdk15on/jars/bcprov-jdk15on-1.61.jar:module-info.class [错误] /Users/jake.stone/.ivy2/cache/javax.xml.bind/jaxb-api/jars/jaxb-api-2.3.1.jar:module-info.class
我不是对Java技术的最新信息,但假设我不能简单地丢弃其中一个课程。
有人可以告诉我我可以使用什么Mergentrategy安全地编译Uber Jar?
答案取决于您的环境和您想要实现的目标。
JDK 8
我使用JDK 8的项目也有同样的问题。JDK8不使用文件module-info.class
,因此可以安全地丢弃文件。
将以下内容添加到您的build.sbt
:
assemblyMergeStrategy in assembly := {
case x if x.endsWith("module-info.class") => MergeStrategy.discard
case x =>
val oldStrategy = (assemblyMergeStrategy in assembly).value
oldStrategy(x)
}
这只是放弃文件。
JDK 11
如果您将JDK 11与最终用户项目(不是库)一起使用,那么它也应该是安全的,好像您创建Uber-jar所有类都包含所有类,并且不需要外部依赖项。只是用简短的测试对其进行了测试(不足以说它总是安全的)。
如果您使用JDK 11并创建库,那么最好不要创建Uber-jar。在这种情况下,module-info.class
的下降很可能会创建一个无法正常工作的罐子。在这种情况下,仅取决于库。
module-info.class
文件已在许多库中移动。这是更新的解决方案
assembly / assemblyMergeStrategy := {
case PathList("module-info.class") => MergeStrategy.last
case path if path.endsWith("/module-info.class") => MergeStrategy.last
case x =>
val oldStrategy = (assembly / assemblyMergeStrategy).value
oldStrategy(x)
}
包含此文件的每个JAR文件都有有关其自己的模块和依赖项的信息,您可以在此处找到更多信息
我没有尝试过,但是我认为适当的策略是对每个JAR文件的内容进行限制,以便将所有模块都包含在此文件中(而不是将最后一个模块作为以前的某些答案)
assemblyMergeStrategy in assembly := {
case x if x.endsWith("module-info.class") => MergeStrategy.concat
case x =>
val oldStrategy = (assemblyMergeStrategy in assembly).value
oldStrategy(x)
}
与先前答案的主要区别在于合并策略:
MergeStrategy.concat