Saya menggunakan SBT (dalam IntelliJ IDEA) untuk membangun proyek Scala sederhana.
Saya ingin tahu cara termudah untuk membuat file Uber JAR (alias Fat JAR, Super JAR).
Saya saat ini menggunakan SBT tetapi ketika saya mengirimkan file JAR saya ke Apache Spark, saya mendapatkan kesalahan berikut:
Pengecualian di thread "main" java.lang.SecurityException: Intisari file tanda tangan tidak valid untuk atribut utama Manifest
Atau kesalahan ini selama waktu kompilasi:
java.lang.RuntimeException: deduplicate: konten file berbeda ditemukan sebagai berikut:
PATH \ DEPENDENCY.jar: META-INF / DEPENDENCIES
PATH \ DEPENDENCY.jar: META-INF / MANIFEST.MF
Ini terlihat seperti itu karena beberapa dependensi saya menyertakan file tanda tangan (META-INF) yang perlu dihapus di final file JAR Uber.
Saya mencoba menggunakan plugin sbt-assembly seperti itu:
/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"
)
)
Ketika saya mengklik " Build Artifact ... " di IntelliJ IDEA saya mendapatkan file JAR. Tapi saya berakhir dengan kesalahan yang sama ...
Saya baru mengenal SBT dan tidak terlalu bereksperimen dengan IntelliJ IDE.
Terima kasih.
META-INF
file - satu entri blog yang mungkin membantu: janschulte.wordpress.com/2014/03/20/…Jawaban:
Akhirnya saya benar-benar melewatkan penggunaan IntelliJ IDEA untuk menghindari menimbulkan kebisingan dalam pemahaman global saya :)
Saya mulai membaca tutorial SBT resmi .
Saya membuat proyek saya dengan struktur file berikut:
Menambahkan plugin sbt-assembly di file assembly.sbt saya . Mengizinkan saya membuat JAR yang gemuk:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
Build.sbt minimal saya terlihat seperti:
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 } }
Catatan : Cara
% "provided"
untuk tidak menyertakan dependensi di JAR lemak akhir (pustaka tersebut sudah termasuk dalam pekerja saya)Catatan : Pembuangan META-INF terinspirasi oleh jawaban ini .
Catatan : Arti
%
dan%%
Sekarang saya dapat membuat JAR gemuk saya menggunakan SBT ( cara menginstalnya ) dengan menjalankan perintah berikut di folder root / my-project :
JAR lemak saya sekarang terletak di folder yang dibuat / target baru :
/my-project/target/scala-2.11/my-project-assembly-1.0.jar
Harapan yang membantu orang lain.
Bagi mereka yang ingin menanamkan SBT dalam IntelliJ IDE: Bagaimana cara menjalankan tugas sbt-assembly dari dalam IntelliJ IDEA?
sumber
Proses 3 Langkah Untuk Membangun Uber JAR / Fat JAR di IntelliJ Idea:
Uber JAR / Fat JAR : File JAR yang memiliki semua dependensi libraray eksternal di dalamnya.
Menambahkan plugin SBT Assembly di IntelliJ Idea
Buka file ProjectName / project / target / plugins.sbt dan tambahkan baris ini
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
Menambahkan Merge, Discard dan Do Not Add strategy di build.sbt
Buka file ProjectName / build.sbt dan tambahkan Strategi Pengemasan JAR Uber
Merge Strategy: Jika ada konflik dalam dua paket tentang sebuah versi library, paket mana yang akan dikemas di Uber JAR.
Strategi Buang: Untuk menghapus beberapa file dari perpustakaan yang tidak ingin Anda paketkan di Uber JAR.
Jangan Tambahkan Strategi: Jangan menambahkan beberapa paket ke Uber JAR.
Misalnya:
spark-core
sudah ada di Spark Cluster Anda, jadi kami tidak boleh mengemasnya di Uber JARGabungkan Kode Dasar Strategi dan Buang Strategi:
assemblyMergeStrategy in assembly := { case PathList("META-INF", xs @ _*) => MergeStrategy.discard case x => MergeStrategy.first }
Jadi, Anda meminta untuk membuang file META-INF menggunakan perintah ini
MergeStrategy.discard
dan untuk file lainnya yang Anda ambil adalah kejadian pertama dari file perpustakaan jika ada konflik dengan menggunakan perintah iniMergeStrategy.first
.Jangan Tambahkan Kode Dasar Strategi:
libraryDependencies += "org.apache.spark" %% "spark-core" % "1.4.1" %"provided"
Jika kami tidak ingin menambahkan spark-core ke file Uber JAR kami karena sudah ada di clutser kami, jadi kami menambahkan
% "provided"
dependensi library di bagian akhir.Membangun Uber JAR dengan semua dependensinya
Dalam tipe terminal
sbt assembly
untuk membangun paketVoila !!! Uber JAR dibuat. JAR akan ada di ProjectName / target / scala-XX
sumber
Tambahkan baris berikut ke project / plugins.sbt Anda
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
Tambahkan berikut ini ke build.sbt Anda
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 }
Strategi penggabungan Assembly digunakan untuk menyelesaikan konflik yang terjadi saat membuat fat jar.
sumber