IntelliJ IDEA内でSBTを使用してUber JAR(脂肪JAR)を構築する方法


90

私はSBT(IntelliJ IDEA内)を使用して単純なScalaプロジェクトを構築しています。

Uber JARファイル(別名Fat JAR、Super JAR)を作成する最も簡単な方法は何ですか?

現在SBTを使用していますが、JARファイルをApache Sparkに送信すると、次のエラーが発生します。

スレッド「メイン」の例外java.lang.SecurityException:マニフェストのメイン属性の無効な署名ファイルダイジェスト

または、コンパイル時のこのエラー:

java.lang.RuntimeException:deduplicate:次の場所にある異なるファイルの内容:
PATH \ DEPENDENCY.jar:META-INF / DEPENDENCIES
PATH \ DEPENDENCY.jar:META-INF / MANIFEST.MF

それはのように見える私の依存関係のいくつかは、最終的なユーバーのJARファイルで削除する必要が署名ファイル(META-INF)が含まれているため、それはです。

私はそのような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"
    )
  )

IntelliJ IDEAで[ Build Artifact ... ]をクリックすると、JARファイルが表示されます。しかし、私は同じエラーに終わります...

私はSBTに不慣れで、IntelliJ IDEをあまり試していません。

ありがとう。


2
物事の音であなたが外にフィルタする必要があるかもしれませんMETA-INF-ファイル1回のブログ記事そのかもしれないが:ヘルプjanschulte.wordpress.com/2014/03/20/...
ショーン・ビエラ

回答:


144

最後に、IntelliJ IDEAの使用を完全にスキップして、私のグローバルな理解にノイズが発生するのを防ぎます:)

私は公式のSBTチュートリアルを読み始めました。

次のファイル構造でプロジェクトを作成しました。

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

私のassembly.sbtファイルにsbt-assembly プラグインを追加しました。太い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")        
  )

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

% "provided"依存関係を最終的なファットJARに含めない方法(これらのライブラリはすでにワーカーに含まれています)

このanswserに触発された META-INFの破棄。

:の意味%%%

/ my-projectルートフォルダーで次のコマンドを実行して、SBT(インストール方法)を使用してファットJARを構築できます。

sbt assembly

私のファットJARは、新しく生成された/ targetフォルダーにあります。

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

それが他の誰かを助けることを願っています。


IntelliJ IDE内でSBTを組み込みたい場合:IntelliJ IDEA内からsbt-assemblyタスクを実行する方法は?


2
Databricksからユーバー-瓶からスパークを除くの[問題でJava / Mavenの提案databricks.gitbooks.io/databricks-spark-knowledge-base/content/...
JimLohse


1
古いMETA-INFを破棄する理由は何ですか?
16

2
注:「提供済み」という%は、依存関係を最終的なファットJARに含めないことを意味します。
Jayasagar 2017年

これは利用可能な唯一のプラグインであり、公式でもなく、sbtのバージョン間でさえ機能しないことに真剣に驚いた
Abhinandan Dubey

40

IntelliJ IdeaでUber JAR / Fat JARを構築するための3ステッププロセス:

Uber JAR / Fat JAR:すべての外部libraray依存関係が含まれているJARファイル。

  1. IntelliJ IdeaにSBTアセンブリプラグインを追加する

    プラグインのsbtパス

    行くプロジェクト名/プロジェクト/ターゲット/ plugins.sbtファイルと、この行を追加します。addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")

  2. build.sbtにMerge、Discard、Do Not Addストラテジーを追加

    sbtパスの構築

    ProjectName / build.sbtファイルに移動し、Uber JARのパッケージ化戦略を追加します

    マージ戦略:ライブラリのバージョンについて2つのパッケージで競合が発生した場合、どちらをUber JARにパックするか。
    破棄戦略: Uber JARにパッケージ化したくないファイルをライブラリから削除します。
    戦略を追加しない: Uber JARにパッケージを追加しないでください。
    exの場合:spark-coreSparkクラスターにすでに存在するため、これをUber JARにパッケージ化しないでください

    戦略のマージと戦略の破棄の基本コード:

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

    したがって、このコマンドMergeStrategy.discardを使用してMETA-INFファイルを破棄することを求めています。残りのファイルについては、このコマンドを使用して競合が発生した場合は、最初に発生するライブラリファイルを取得しますMergeStrategy.first

    戦略の基本コードを追加しないでください:

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

    すでにclutserにあるため、Uber JARファイルにスパークコアを追加したくない場合は、% "provided"ライブラリ依存関係の最後に追加します。

  3. すべての依存関係を持つUber JARをビルドする

    sbtassembly

    sbt assemblyパッケージを構築するためのターミナルタイプ


出来上がり!!! Uber JARがビルドされます。JARはProjectName / target / scala-XXにあります

JarBuilt


16

次の行をproject / 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
}

アセンブリマージ戦略は、ファットjarの作成時に発生した競合を解決するために使用されます。


1
コンソールで「sbtアセンブリ」を実行すると、太いJarを作成できます
ARMV

2
scalaバージョン2.11.8(SBTバージョン:0.13.12)の場合、addSbtPlugin( "com.eed3si9n"% "sbt-assembly"% "0.12.0")をproject / assembly.sbtに
書き込みます
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.