Как построить Uber JAR (FAT JAR) с использованием SBT в IntelliJ IDEA?
Я использую SBT (в IntelliJ IDEA) для создания простого проекта Scala.
Я хотел бы знать, что является самым простым способом создания файла Uber JAR (он же Fat JAR, Super JAR).
В настоящее время я использую SBT, но когда я отправляю свой JAR-файл в Apache Spark, я получаю следующую ошибку:
- В чем смысл использования подчеркивания в Scala?
- Почему функция Array's == возвращает true для Array (1,2) == Array (1,2)?
- Вызовите по имени vs call по значению в Scala, необходимо разъяснение
- Отладка Scala-кода с помощью простого-build-инструмента (sbt) и IntelliJ
- Разница между использованием атрибута приложения и основным методом в scala
Исключение в streamе «main» java.lang.SecurityException: Недопустимый дайджест файла подписи для основных атрибутов манифеста
Или эта ошибка во время компиляции:
java.lang.RuntimeException: deduplicate: различное содержимое файла, найденное в следующем:
PATH \ DEPENDENCY.jar: META-INF / ЗАВИСИМОСТИ
PATH \ DEPENDENCY.jar: META-INF / MANIFEST.MF
Похоже , что некоторые из моих зависимостей include файлы подписи (META-INF), которые необходимо удалить в финальном файле Uber JAR.
Я попытался использовать плагин 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" ) )
Когда я нажимаю « Build Artifact … » в IntelliJ IDEA, я получаю файл JAR. Но в итоге я получаю ту же ошибку …
Я новичок в SBT и не очень экспериментировал с IntelliJ IDE.
Благодарю.
- Использование _ в scala lambda-функциях
- Почему объектные объекты более объектно-ориентированные?
- Как работает «scala.sys.process» от Scala 2.9?
- Как вы делаете инъекцию зависимостей с шаблоном Cake без hardcoding?
- Как импортировать build.gradle в IntelliJ
- Скала для странного поведения
- Когда использовать знак равенства в объявлении метода Scala?
- В Scala есть оператор присваивания «=» вызов метода?
Наконец, я полностью пропускаю использование IntelliJ IDEA, чтобы избежать генерации шума в моем глобальном понимании 🙂
Я начал читать официальный учебник SBT .
Я создал свой проект со следующей файловой структурой:
my-project/project/assembly.sbt my-project/src/main/scala/myPackage/MyMainObject.scala my-project/build.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") ) 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 } }
Примечание . % "provided"
означает не включать зависимость в конечной толчке JAR (эти библиотеки уже включены в мои работники)
Примечание : META-INF отбрасывается воодушевлением этого answser .
Примечание : значение %
и %%
Теперь я могу построить свой полный JAR с помощью SBT ( как его установить ), выполнив следующую команду в корневой папке / my-project :
sbt assembly
Мой толстый JAR теперь находится в новой сгенерированной / целевой папке:
/my-project/target/scala-2.11/my-project-assembly-1.0.jar
Надеюсь, что это помогает кому-то другому.
Для тех, кто хочет внедрить SBT в IntelliJ IDE: как запускать задачи сборки sbt из IntelliJ IDEA?
3 Шаг процесса для создания Uber JAR / Fat JAR в IntelliJ Идея:
Uber JAR / FAT JAR : JAR-файл, имеющий все внешние зависимости между библиотеками.
-
Добавление плагина сборки SBT в IntelliJ Idea
Перейдите в ProjectName / project / target / plugins.sbt файл и добавьте эту строку
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
-
Добавление слияния, удаления и не добавления страtagsи в build.sbt
Перейдите в файл ProjectName / build.sbt и добавьте Страtagsю упаковки Uber JAR
Страtagsя слияния: если есть конфликт в двух пакетах о версии библиотеки, то какой из них нужно упаковать в Uber JAR.
Страtagsя удаления : удалить некоторые файлы из библиотеки, которые вы не хотите упаковывать в Uber JAR.
Не добавлять страtagsю: не добавляйте пакет в Uber JAR.
Например:spark-core
будет уже присутствовать на вашем Spark Cluster. Поэтому мы не должны упаковывать это в Uber JARСтраtagsя объединения и отказ от страtagsи. Основной код:
assemblyMergeStrategy in assembly := { case PathList("META-INF", xs @ _*) => MergeStrategy.discard case x => MergeStrategy.first }
Поэтому вы просите отменить файлы META-INF, используя эту команду
MergeStrategy.discard
и для остальной части файлов, которые вы берете первое вхождение файла библиотеки, если есть конфликт, используя эту командуMergeStrategy.first
.Не добавлять страtagsческий код:
libraryDependencies += "org.apache.spark" %% "spark-core" % "1.4.1" %"provided"
Если мы не хотим добавлять искровое kernel в наш 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 }
Страtagsя слияния Ассамблеи используется для разрешения конфликтов, возникающих при создании толстой банки.