Я использую SBT (в IntelliJ IDEA) для создания простого проекта Scala.
Я хотел бы знать, как проще всего создать файл Uber JAR (он же Fat JAR, Super JAR).
В настоящее время я использую SBT, но когда я отправляю свой JAR-файл в Apache Spark, я получаю следующую ошибку:
Исключение в потоке "main" java.lang.SecurityException: недействительный дайджест файла подписи для основных атрибутов манифеста
Или эта ошибка во время компиляции:
java.lang.RuntimeException: deduplicate: различное содержимое файла, обнаруженное в следующем:
PATH \ DEPENDENCY.jar: META-INF / DEPENDENCIES
PATH \ DEPENDENCY.jar: META-INF / MANIFEST.MF
Это выглядит как это происходит потому , что некоторые из моих зависимостей включают файлы сигнатур (META-INF) , который должен быть удален в конечном файле JAR Uber.
Я пробовал использовать плагин sbt-assembly вот так:
/project/assembly.sbt
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
/project/plugins.sbt
logLevel := Level.Warn
/build.sbt
lazy val commonSettings = Seq(
name := "Spark-Test"
version := "1.0"
scalaVersion := "2.11.4"
)
lazy val app = (project in file("app")).
settings(commonSettings: _*).
settings(
libraryDependencies ++= Seq(
"org.apache.spark" %% "spark-core" % "1.2.0",
"org.apache.spark" %% "spark-streaming" % "1.2.0",
"org.apache.spark" % "spark-streaming-twitter_2.10" % "1.2.0"
)
)
Когда я нажимаю « Создать артефакт ... » в IntelliJ IDEA, я получаю файл JAR. Но я получаю ту же ошибку ...
Я новичок в SBT и не очень экспериментировал с IntelliJ IDE.
Спасибо.
META-INF
файлы - одно сообщение в блоге, которое может помочь: janschulte.wordpress.com/2014/03/20/…Ответы:
Наконец, я полностью пропускаю использование IntelliJ IDEA, чтобы не создавать шума в моем глобальном понимании :)
Я начал читать официальное руководство по SBT .
Я создал свой проект со следующей файловой структурой:
Добавлен плагин sbt-assembly в мой файл assembly.sbt . Позволив мне создать толстый JAR:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
Мой минимальный build.sbt выглядит так:
lazy val root = (project in file(".")). settings( name := "my-project", version := "1.0", scalaVersion := "2.11.4", mainClass in Compile := Some("myPackage.MyMainObject") ) val sparkVersion = "1.2.0" libraryDependencies ++= Seq( "org.apache.spark" %% "spark-core" % sparkVersion % "provided", "org.apache.spark" %% "spark-streaming" % sparkVersion % "provided", "org.apache.spark" %% "spark-streaming-twitter" % sparkVersion ) // META-INF discarding mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) => { case PathList("META-INF", xs @ _*) => MergeStrategy.discard case x => MergeStrategy.first } }
Примечание :
% "provided"
средство не включать зависимость в окончательный JAR-файл с жиром (эти библиотеки уже включены в мои рабочие)Примечание. Отказ от META-INF вдохновлен этим ответчиком .
Примечание : значение
%
и%%
Теперь я могу создать свой толстый JAR с помощью SBT ( как его установить ), выполнив следующую команду в корневой папке my / my-project :
Мой толстый JAR теперь находится в новой сгенерированной / целевой папке:
/my-project/target/scala-2.11/my-project-assembly-1.0.jar
Надеюсь, это поможет кому-то другому.
Для тех, кто хочет встроить SBT в IntelliJ IDE: как запускать задачи sbt-assembly из IntelliJ IDEA?
источник
Трехэтапный процесс создания Uber JAR / Fat JAR в IntelliJ Idea:
Uber JAR / Fat JAR : JAR-файл, в котором есть все внешние зависимости libraray.
Добавление подключаемого модуля SBT Assembly в IntelliJ Idea
Перейдите в файл ProjectName / project / target / plugins.sbt и добавьте эту строку
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
Добавление стратегии слияния, удаления и отказа от добавления в build.sbt
Перейдите в файл ProjectName / build.sbt и добавьте стратегию упаковки Uber JAR.
Стратегия слияния: если в двух пакетах есть конфликт из-за версии библиотеки, то какую из них упаковать в Uber JAR.
Стратегия сброса: удалить из библиотеки некоторые файлы, которые вы не хотите упаковывать в Uber JAR.
Не добавлять стратегию: не добавлять какой-либо пакет в Uber JAR.
Например:
spark-core
уже будет присутствовать в вашем кластере Spark, поэтому мы не должны упаковывать его в Uber JAR.Базовый код стратегии слияния и стратегии отмены:
assemblyMergeStrategy in assembly := { case PathList("META-INF", xs @ _*) => MergeStrategy.discard case x => MergeStrategy.first }
Таким образом, вы просите удалить файлы META-INF с помощью этой команды,
MergeStrategy.discard
а для остальных файлов вы берете первое вхождение файла библиотеки, если с помощью этой команды возникает какой-либо конфликтMergeStrategy.first
.Не добавляйте базовый код стратегии:
libraryDependencies += "org.apache.spark" %% "spark-core" % "1.4.1" %"provided"
Если мы не хотим добавлять искровое ядро в наш файл Uber JAR, поскольку он уже находится в нашем clutser, мы добавляем
% "provided"
в конце его библиотечную зависимость.Сборка Uber JAR со всеми его зависимостями
В типе терминала
sbt assembly
для сборки пакетаВуаля !!! Uber JAR построен. JAR будет в ProjectName / target / scala-XX
источник
Добавьте следующую строку в свой проект / plugins.sbt
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
Добавьте следующее в свой build.sbt
mainClass in assembly := some("package.MainClass") assemblyJarName := "desired_jar_name_after_assembly.jar" val meta = """META.INF(.)*""".r assemblyMergeStrategy in assembly := { case PathList("javax", "servlet", xs @ _*) => MergeStrategy.first case PathList(ps @ _*) if ps.last endsWith ".html" => MergeStrategy.first case n if n.startsWith("reference.conf") => MergeStrategy.concat case n if n.endsWith(".conf") => MergeStrategy.concat case meta(_) => MergeStrategy.discard case x => MergeStrategy.first }
Стратегия объединения сборок используется для разрешения конфликтов, возникших при создании толстой банки.
источник