Разрешение зависимостей при создании JAR через сборку SBT

Я хочу создать большой файл Jar. для которого я пытаюсь использовать SBT ASSEMBLY. Я установил sbt-assembly из GitHub и этот ответ. Когда я запустил 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 для каждой из них по отдельности решило проблему.


person Learner    schedule 26.10.2013    source источник


Ответы (2)


Я думаю, вы пытаетесь лечить симптомы, но ваша проблема на самом деле не в сборке: в вашем проекте есть библиотека дважды в двух разных версиях по пути к классам (javax.servlet).

Если эти версии совместимы с бинарными файлами (чего я не знаю), вы можете исключить одно из двух вхождений в файле сборки вот так. Если они несовместимы, вам нужно будет развернуть граф зависимостей (хорошим способом сделать это может быть sbt-dependency-graph plugin) и попытайтесь найти соответствующие версии.

В любом случае может быть полезно (хотя бы временно) хранить библиотеки в папке проекта. Если вы добавите retrieveManaged in ThisBuild := true в файл сборки sbt, все библиотеки будут найдены в <project-root>/lib_managed. Это позволяет вам видеть, какие банки на самом деле там.


EDIT: отображение графика зависимостей:

Добавить к project/plugins.sbt:

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

Добавить к build.sbt:

net.virtualvoid.sbt.graph.Plugin.graphSettings

Затем запустите sbt dependency-graph.

person 0__    schedule 26.10.2013
comment
Спасибо! На самом деле, я уже добавил аргумент retrieveManaged в файл sbt. Я вижу банку, которая вызывает эту проблему, под lib_managed/jars/org.mortbay.jetty/servlet-api/. По ссылке я добавил [обновление 2, о котором идет речь], и все же я сталкиваюсь с проблемой. Как найти точную библиотеку, которая вызывает проблему? - person Learner; 27.10.2013
comment
Вы использовали плагин графика зависимостей? Это должно помочь вам узнать, откуда взялась банка. Я добавил информацию. - person 0__; 27.10.2013
comment
У меня есть указанное выше дерево зависимостей. Любые указатели на то, как мне обойти эту ошибку MergeStrategy? - person Learner; 27.10.2013
comment
Я не вижу javax.servlet-2.5.0.v201103041518.jar в вашей распечатке. В любом случае, если вы найдете артефакт, на который он ссылается, вы можете добавить туда оператор exclude, надеясь, что вы не столкнетесь с несовместимостью бинарного класса. Если вы делаете (например, есть AbstractMethodError), единственное решение — найти версии ваших зависимостей, которые имеют совпадающую версию для этой библиотеки. Если ничего не получится, вам, возможно, придется разветвить один из этих проектов и скомпилировать его с используемой вами версией servlet-api... - person 0__; 27.10.2013
comment
ой, мой плохой. Я пропустил это javax.servlet-2.5.0.v201103041518.jar! Обновлен вывод графа зависимостей. - person Learner; 27.10.2013

Вы также можете обратиться к Этот технический блог

Создание одного JAR-файла для проекта Spark с помощью sbt-assembly

Этот пост о том, как создать толстую банку для проекта потоковой передачи искры с помощью плагина sbt. sbt-assembly — это плагин sbt для создания большого JAR-файла проекта sbt со всеми его зависимостями.

person USB    schedule 21.04.2014