scala - ¿Cómo construir un Uber JAR(Fat JAR) usando SBT dentro de IntelliJ IDEA?
intellij-idea meta-inf (3)
Agregue la siguiente línea a su proyecto / plugins.sbt
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
Agregue lo siguiente a su 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
}
La estrategia de fusión de ensamblados se usa para resolver conflictos que se produjeron al crear un tarro grueso.
Estoy usando SBT (dentro de IntelliJ IDEA) para construir un proyecto simple de Scala.
Me gustaría saber cuál es la forma más sencilla de crear un archivo Uber JAR (también conocido como Fat JAR, Super JAR).
Actualmente estoy usando SBT pero cuando envío mi archivo JAR a Apache Spark obtengo el siguiente error:
Excepción en el subproceso "main" java.lang.SecurityException: resumen de archivo de firma no válido para los atributos principales del manifiesto
O este error durante el tiempo de compilación:
java.lang.RuntimeException: deduplicate: diferentes contenidos de archivo encontrados en lo siguiente:
RUTA / DEPENDENCIA.jar: META-INF / DEPENDENCIAS
PATH / DEPENDENCY.jar: META-INF / MANIFEST.MF
Parece que se debe a que algunas de mis dependencias incluyen archivos de firma (META-INF) que deben eliminarse en el archivo UAR JAR final.
Traté de usar el sbt-assembly así:
/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"
)
)
Cuando hago clic en " Crear artefacto ... " en IntelliJ IDEA, obtengo un archivo JAR. Pero termino con el mismo error ...
Soy nuevo en SBT y no tengo mucha experiencia con IntelliJ IDE.
Gracias.
Finalmente omito totalmente el uso de IntelliJ IDEA para evitar generar ruido en mi comprensión global :)
Empecé a leer el tutorial oficial de SBT .
Creé mi proyecto con la siguiente estructura de archivos:
my-project/project/assembly.sbt
my-project/src/main/scala/myPackage/MyMainObject.scala
my-project/build.sbt
sbt-assembly plugin sbt-assembly en mi archivo assembly.sbt . Permitiéndome construir un tarro gordo:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
Mi mínimo build.sbt se parece a:
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
}
}
Nota
: El
% "provided"
significa no incluir la dependencia en el JAR gordo final (esas bibliotecas ya están incluidas en mis trabajadores)
Nota : descarte META-INF inspirado en este contestador .
Ahora puedo construir mi JAR gordo usando SBT ( cómo instalarlo ) ejecutando el siguiente comando en mi carpeta raíz / my-project :
sbt assembly
Mi JAR gordo ahora se encuentra en la nueva carpeta generada / objetivo :
/my-project/target/scala-2.11/my-project-assembly-1.0.jar
Espero que ayude a alguien más.
Para aquellos que desean integrar SBT en IntelliJ IDE: ¿Cómo ejecutar tareas de ensamblaje sbt desde IntelliJ IDEA?
Proceso de 3 pasos para construir Uber JAR / Fat JAR en IntelliJ Idea:
Uber JAR / Fat JAR : archivo JAR que contiene todas las dependencias externas de libraray.
-
Agregar el complemento SBT Assembly en IntelliJ Idea
Vaya al archivo ProjectName / project / target / plugins.sbt y agregue esta línea
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
-
Agregar estrategia de combinación, descarte y no agregar en build.sbt
Vaya al archivo ProjectName / build.sbt y agregue la Estrategia para empaquetar un UAR JAR
Estrategia de fusión: si hay un conflicto en dos paquetes sobre una versión de la biblioteca, ¿cuál empaquetar en Uber JAR?
Estrategia de descarte: Para eliminar algunos archivos de la biblioteca que no desea empaquetar en Uber JAR.
No agregue estrategia: no agregue algún paquete a Uber JAR.
Por ejemplo:spark-core
ya estará presente en su Spark Cluster, por lo que no debemos empaquetar esto en Uber JAR
Estrategia de fusión y código básico de estrategia de descarte:
assemblyMergeStrategy in assembly := { case PathList("META-INF", xs @ _*) => MergeStrategy.discard case x => MergeStrategy.first }
Por lo tanto, está solicitando descartar archivos META-INF con este comando
MergeStrategy.discard
y para el resto de los archivos está tomando la primera aparición del archivo de biblioteca si hay algún conflicto al usar este comandoMergeStrategy.first
.No agregue código básico de estrategia:
libraryDependencies += "org.apache.spark" %% "spark-core" % "1.4.1" %"provided"
Si no queremos agregar el núcleo de chispa a nuestro archivo JAR de Uber, ya estará en nuestro clutser, entonces estamos agregando el
% "provided"
al final de la dependencia de la biblioteca.
-
Construyendo Uber JAR con todas sus dependencias
En el conjunto de terminales tipo
sbt assembly
para construir el paquete
Voila !!!
Se construye Uber JAR.
JAR estará en
ProjectName / target / scala-XX