Как построить Uber JAR (Fat JAR) с помощью SBT в IntelliJ IDEA?


Я использую SBT (в IntelliJ IDEA) для создания простого проекта Scala.

Я хотел бы знать, что такое самый простой способ построить Uber JAR file (aka Fat JAR, Super JAR).

В настоящее время я использую SBT, но когда я отправляю свой файл JAR в Apache Spark Я получаю следующую ошибку:

исключение в потоке" main " java.ленг.SecurityException: Недопустимый дайджест файла подписи для Манифеста основные атрибуты

или эта ошибка во время компиляции:

java.ленг.RuntimeException: deduplicate: найдено другое содержимое файла в следующем:
ПУТЬЗАВИСИМОСТЬ.jar: META-INF / DEPENDENCIES
ПУТЬЗАВИСИМОСТЬ.jar: META-INF / MANIFEST.МФ

Это выглядит так: это связано с тем, что некоторые из моих зависимостей включают файлы сигнатур (META-INF), которые необходимо удалить в окончательной банке Uber файл.

Я пытался использовать sbt-assembly плагин вроде этого:

/проекта/сборки.СБТ

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")

/проекта/Плагины.СБТ

logLevel := Level.Warn

/ build.СБТ

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.

спасибо.

3 70

3 ответа:

наконец, я полностью пропускаю использование IntelliJ IDEA, чтобы избежать создания шума в моем глобальном понимании :)

я начал читать официальный учебник SBT.

Я создал свой проект со следующей структурой файлов:

my-project/project/assembly.sbt
my-project/src/main/scala/myPackage/MyMainObject.scala
my-project/build.sbt

добавил sbt-assemblyплагин в своем сборка.СБТ. Позволяя мне построить жирную банку:

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")

мой минимальный построить.СБТ выглядит так :

lazy val root = (project in file(".")).
  settings(
    name := "my-project",
    version := "1.0",
    scalaVersion := "2.11.4",
    mainClass in Compile := Some("myPackage.MyMainObject")        
  )

libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-core" % "1.2.0" % "provided",
  "org.apache.spark" %% "spark-streaming" % "1.2.0" % "provided",
  "org.apache.spark" % "spark-streaming-twitter_2.10" % "1.2.0"
)

// META-INF discarding
mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) =>
   {
    case PathList("META-INF", xs @ _*) => MergeStrategy.discard
    case x => MergeStrategy.first
   }
}

Примечание: The % "provided" означает не включать зависимость в окончательный fat JAR (эти библиотеки уже включены в мои рабочие)

Примечание: META-INF отбрасывание вдохновленный этим ответчиком.

Примечание: значение % и %%

теперь я могу построить свой жир банку с помощью SBT (как установить это), выполнив следующую команду в my / my-project корневую папку:

sbt assembly

моя жирная банка теперь находится в новом сгенерированном / target:

/my-project/target/scala-2.11/my-project-assembly-1.0.jar

надеюсь, что это поможет кому-то еще.


для тех, кто хочет присвоить SBT в IntelliJ IDE: как запустить задачи sbt-сборки из IntelliJ IDEA?

3 шага для создания jar-файл/жир Jar в IntelliJ идея:

Uber JAR / Fat JAR : JAR-файл, имеющий все внешние зависимости libraray в нем.

  1. добавление плагина сборки SBT в IntelliJ Idea

    Plugin sbt Path

    на имя проекта / проект / цель / Плагины.СБТ и добавить эту строку addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")

  2. добавление слияния, отбросить и не добавлять стратегия в построении.СБТ

    Build sbt Path

    на имя_проекта/строить.СБТ файл и добавить стратегию для упаковки Uber JAR

    Стратегия Объединения : если есть конфликт в двух пакетах о версии библиотеки, то какой из них упаковать в Uber JAR.
    Отменить Стратегию : чтобы удалить некоторые файлы из библиотеки, которые вы не хотите упаковать в Uber JAR.
    не добавлять Стратегия: не добавляйте какой-либо пакет в Uber JAR.
    например: spark-core уже будет присутствовать на вашей Искре Cluster.So мы не должны упаковать это в 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"

    если мы не хотим добавлять spark-core в наш файл Uber JAR, как это будет уже на нашем clutser, поэтому мы добавляем % "provided" в конце его зависимость от библиотеки.

  3. создание Uber JAR со всеми его зависимостями

    sbtassembly

    в типе терминала sbt assembly для наращивания пакет


Вуаля!!! Uber JAR построен. Банку будет ProjectName / target / scala-XX

JarBuilt

добавьте следующую строку в ваш проект/Плагины.СБТ

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")

добавьте в свою сборку следующее.СБТ

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
}

стратегия слияния сборок используется для разрешения конфликтов, возникающих при создании fat jar.