4

我想创建一个大 Jar 文件。我正在尝试使用SBT ASSEMBLY我从GitHub和这个答案安装了 sbt-assembly 。当我跑的时候sbt assembly,我得到了这个错误:

java.lang.RuntimeException: deduplicate: different file contents found in the following:
/home/UserName/.ivy2/cache/org.eclipse.jetty.orbit/javax.servlet/orbits/javax.servlet-2.5.0.v201103041518.jar:javax/servlet/SingleThreadModel.class
/home/UserName/.ivy2/cache/org.mortbay.jetty/servlet-api/jars/servlet-api-2.5-20081211.jar:javax/servlet/SingleThreadModel.class

为了解决这个问题,我关注了用户的 README 页面,这是他建议的代码。

mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) =>
  {
    case PathList("org", "apache", xs @ _*) => MergeStrategy.last
    case PathList("javax", "servlet", xs @ _*) => MergeStrategy.last
    case PathList("com", "esotericsoftware", xs @ _*) => MergeStrategy.last
    case PathList("project.clj") => MergeStrategy.last
    case PathList("overview.html") => MergeStrategy.last
    case x => old(x)
  }
}

即使在添加此代码之后,我也会收到之前提到的相同错误。请让我知道我错过了什么。对此错误的任何帮助将不胜感激。谢谢!

更新 2:

根据给出的链接添加排除规则,

libraryDependencies ++= Seq("org.apache.spark" %% "spark-core" % "0.8.0-incubating","com.codahale" % "jerkson_2.9.1" % "0.5.0","org.skife.com.typesafe.config" % "typesafe-config" % "0.3.0").map(_.exclude("javax", "servlet"))

更新 3:

我可以找到导致问题的库。

| +-org.apache.avro:avro-ipc:1.7.4
| | +-io.netty:netty:3.4.0.Final (evicted by: 3.5.4.Final)
| | +-io.netty:netty:3.5.4.Final
...
...
| | +-org.mortbay.jetty:jetty-util:6.1.26
| | +-org.mortbay.jetty:jetty:6.1.26
| | | +-org.mortbay.jetty:jetty-util:6.1.26
| | | +-org.mortbay.jetty:servlet-api:2.5-20081211
| | | 
| | +-org.mortbay.jetty:servlet-api:2.5-20081211
| | +-org.slf4j:slf4j-api:1.7.2
...
... 
| +-org.eclipse.jetty:jetty-server:7.6.8.v20121106
| | +-org.eclipse.jetty.orbit:javax.servlet:2.5.0.v201103041518

更新 4:修复

所以添加 MergeStrategy 确实解决了这个问题。即使我有很多依赖项,超过 10 个,为每个依赖项添加 MergeStrategy 单独解决了这个问题。

4

2 回答 2

4

javax.servlet我认为您正在尝试治疗这些症状,但您的问题实际上不是汇编:您的项目在类路径 ( )上有两个不同版本的库。

如果这些版本是二进制兼容的(我不知道),您可以通过在构建文件中排除两个出现的其中一个,就像这样。如果它们不兼容,您将需要展开您的依赖关系图(一个很好的方法可能是sbt-dependency-graph插件)并尝试找到匹配的版本。

在任何情况下,(至少暂时)将库保存在项目文件夹中可能很有用。如果你添加retrieveManaged in ThisBuild := true到你的 sbt 构建文件,所有的库都将在<project-root>/lib_managed. 这使您可以查看实际存在哪些罐子。


编辑:显示依赖关系图:

添加到project/plugins.sbt

addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.7.4")

添加到build.sbt

net.virtualvoid.sbt.graph.Plugin.graphSettings

然后运行sbt dependency-graph

于 2013-10-26T13:56:50.167 回答
4

你也可以参考这个技术博客

使用 sbt-assembly 为 Spark 项目创建单个 JAR

这篇文章是关于如何使用 sbt 插件为 spark 流项目创建一个 fat jar。sbt-assembly 是一个 sbt 插件,用于创建一个包含所有依赖项的 sbt 项目的胖 JAR。

于 2014-04-21T10:54:21.433 回答