IntelliJ IDEA'da SBT kullanarak bir Uber JAR (Fat JAR) nasıl oluşturulur?


92

Basit bir Scala projesi oluşturmak için SBT (IntelliJ IDEA içinde) kullanıyorum.

Bir Uber JAR dosyası (diğer adıyla Fat JAR, Super JAR) oluşturmanın en basit yolunun ne olduğunu bilmek istiyorum .

Şu anda SBT kullanıyorum ancak JAR dosyamı Apache Spark'a gönderirken aşağıdaki hatayı alıyorum:

"Main" iş parçacığında istisna java.lang.SecurityException: Manifest ana öznitelikleri için geçersiz imza dosyası özeti

Veya derleme sırasında bu hata:

java.lang.RuntimeException: tekilleştirme: aşağıda bulunan farklı dosya içerikleri:
PATH \ DEPENDENCY.jar: META-INF / DEPENDENCIES
PATH \ DEPENDENCY.jar: META-INF / MANIFEST.MF

Bu gibi görünüyor benim bağımlılıkları bazı nihai Uber JAR dosyasında kaldırılması gerekir imza dosyalarını (META-INF) içerdikleri öyle.

Sbt-assembly eklentisini şu şekilde kullanmaya çalıştım :

/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'da " Yapı Oluştur ... " seçeneğini tıkladığımda bir JAR dosyası alıyorum. Ama aynı hatayla sonuçlanıyorum ...

SBT'de yeniyim ve IntelliJ IDE ile pek deneyime sahip değilim.

Teşekkürler.


2
Görünüşe göre , META-INFdosyaları filtrelemeniz gerekebilir - yardımcı olabilecek bir blog yazısı : janschulte.wordpress.com/2014/03/20/…
Sean Vieira

Yanıtlar:


147

Son olarak, global anlayışımda gürültü üretmekten kaçınmak için IntelliJ IDEA kullanmayı tamamen atlıyorum :)

Resmi SBT eğitimini okumaya başladım .

Projemi aşağıdaki dosya yapısıyla oluşturdum:

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

Eklenen sbt montaj eklentisi benim de assembly.sbt dosyası. Şişman bir KAVANOZ yapmama izin veren:

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

Minimal build.sbt'm şöyle görünüyor:

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
   }
}

Not : % "provided"Bağımlılığı nihai yağ JAR'ına dahil etmeme araçları (bu kütüphaneler zaten işçilerim arasında yer alıyor)

Not : META-INF , bu yanıtlayıcıdan esinlenerek atılır .

Not : anlamı %ve%%

Şimdi, / my-project kök klasörümde aşağıdaki komutu çalıştırarak, SBT kullanarak ( nasıl kurulur ) fat JAR'ımı oluşturabilirim :

sbt assembly

Fat JAR'ım artık yeni oluşturulan / hedef klasörde bulunuyor:

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

Umarım bu başka birine yardımcı olur.


SBT'yi IntelliJ IDE'ye katıştırmak isteyenler için: IntelliJ IDEA içinden sbt-assembly görevleri nasıl çalıştırılır?




1
Eski META-INF'in atılmasının nedeni nedir?
2016

2
Not: "Sağlanan" yüzdesi, bağımlılığı son yağ JAR'ına dahil etmemek anlamına gelir, bana yardımcı olandır!
Jayasagar

Bunun mevcut tek eklenti olmasına ciddi şekilde şaşırdım - resmi bile değil ve sbt sürümlerinde bile çalışmıyor
Abhinandan Dubey

40

IntelliJ Fikrinde Uber JAR / Fat JAR Oluşturmak İçin 3 Adımlı İşlem:

Uber JAR / Fat JAR : İçinde tüm harici kitaplık bağımlılıklarının bulunduğu JAR dosyası.

  1. IntelliJ Idea'da SBT Assembly eklentisi ekleme

    Eklenti sbt Yolu

    Git ProjeAdı / proje / hedefin / plugins.sbt dosya ve bu satırı ekleyinaddSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")

  2. Build.sbt'de Birleştirme, Atma ve Ekleme stratejisi ekleme

    Sbt Yolu Oluştur

    Git ProjeAdı / build.sbt dosyası ve bir Über JAR Ambalaj Stratejisi eklemek

    Birleştirme Stratejisi: Bir kitaplık sürümüyle ilgili iki pakette çakışma varsa, hangisinin Uber JAR'da paketleneceği.
    Silme Stratejisi: Uber JAR'da paketlemek istemediğiniz bazı dosyaları kitaplıktan kaldırmak için.
    Strateji Eklemeyin: Uber JAR'a paket eklemeyin.
    Örneğin: spark-coreSpark Cluster'ınızda zaten mevcut olacak, bu yüzden bunu Uber JAR'da paketlememeliyiz

    Strateji Birleştirme ve Atma Stratejisi Temel Kodu:

    assemblyMergeStrategy in assembly := { case PathList("META-INF", xs @ _*) => MergeStrategy.discard case x => MergeStrategy.first }

    Dolayısıyla, bu komutu kullanarak META-INF dosyalarını atmayı istiyorsunuz MergeStrategy.discardve geri kalan dosyalar için, bu komutu kullanarak herhangi bir çakışma varsa, kitaplık dosyasının ilk oluşumunu alıyorsunuz MergeStrategy.first.

    Strateji Temel Kodunu Eklemeyin:

    libraryDependencies += "org.apache.spark" %% "spark-core" % "1.4.1" %"provided"

    Spark-core'u Uber JAR dosyamıza zaten clutser'ımızda olacağı için eklemek istemiyorsak, % "provided"en sonunda kitaplık bağımlılığı ekliyoruz .

  3. Tüm bağımlılıkları ile Uber JAR oluşturma

    sbtassembly

    sbt assemblyPaketi oluşturmak için terminal tipinde


Voila !!! Uber JAR inşa edildi. JAR, ProjectName / target / scala-XX içinde olacak

JarBuilt


16

Aşağıdaki satırı projenize / plugins.sbt'ye ekleyin

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

Aşağıdakileri build.sbt dosyanıza ekleyin

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
}

Derleme birleştirme stratejisi, şişman kavanoz oluştururken meydana gelen çatışmaları çözmek için kullanılır.


1
Konsolda "sbt montajını" çalıştırarak şişman Kavanoz oluşturabilirsiniz
ARMV

2
scala sürüm 2.11.8 için (SBT sürümü: 0.13.12) addSbtPlugin ("com.eed3si9n"% "sbt-assembly"% "0.12.0") proje / assembly.sbt
ARMV
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.