sbt 程序集:删除重复模块-info.class

sbt assembly: deduplicate module-info.class

我在组装 uber jar 时遇到以下错误:

java.lang.RuntimeException: deduplicate: different file contents found in the following: [error] /Users/jake.stone/.ivy2/cache/org.bouncycastle/bcprov-jdk15on/jars/bcprov-jdk15on-1.61.jar:module-info.class [error] /Users/jake.stone/.ivy2/cache/javax.xml.bind/jaxb-api/jars/jaxb-api-2.3.1.jar:module-info.class

我不是最新的 java 技术,但假设我不能简单地丢弃其中之一 类。

谁能告诉我可以使用什么 mergeStrategy 来安全地编译 uber jar?

答案取决于您的环境和您想要实现的目标。

JDK 8

我在使用 JDK 8 的项目中遇到了同样的问题。JDK 8 不使用文件 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)
}

这只是丢弃文件。

JDK11

如果您将 JDK 11 与最终用户项目(而不是库)一起使用,那么它也应该是安全的,就像您创建 uber-jar 一样,所有 类 都包含在内并且没有外部依赖项是需要的。刚刚用一个简短的测试对其进行了测试(不够彻底,不能说它总是安全的)。

如果您使用 JDK 11 并创建一个库,那么最好不要创建一个 uber-jar。在这种情况下,删除 module-info.class 很可能会创建一个无法运行的 jar。在这种情况下,只依赖于库。

module-info.class 文件已在许多库中移动。 这是更新的解决方案

ThisBuild / assemblyMergeStrategy  := {
  case PathList("module-info.class") => MergeStrategy.discard
  case x if x.endsWith("/module-info.class") => MergeStrategy.discard
  case x =>
    val oldStrategy = (ThisBuild / assemblyMergeStrategy).value
    oldStrategy(x)
}