我想创建一个大的Jar文件。我尝试使用 SBT ASSEMBLY 。我从GitHub和此 answer安装了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:
根据给定的链接添加了exlusion规则,
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 解决了这个问题。
答案 0 :(得分:4)
我认为您正在尝试处理症状,但您的问题实际上不是汇编:您的项目在类路径(javax.servlet
)上有两个不同版本的库两次。
如果这些版本是二进制兼容的(我不知道),你可以通过在构建文件like so中排除这两个版本中的一个来完成。如果它们不兼容,您将需要展开您的依赖关系图(这可能是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
。
答案 1 :(得分:4)
您也可以参考This Tech Blog
使用sbt-assembly
为Spark项目创建单个JAR这篇文章是关于如何使用sbt插件为火花流项目创建一个胖罐。 sbt-assembly是一个sbt插件,用于创建一个包含所有依赖项的sbt项目的胖JAR。