SBT组件:DEDUPERICATE模块Info.class



我在组装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

相关内容

最新更新