web-dev-qa-db-ja.com

IntelliJ IDEAでSBTを使用してUber JAR(Fat JAR)を構築する方法は?

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

最も簡単な方法が何であるかを知りたいUber JARファイル(別名Fat JAR、Super JAR)。

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

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

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

Java.lang.RuntimeException:重複排除:異なるファイルの内容は次の場所にあります:
PATH\DEPENDENCY.jar:META-INF/DEPENDENCIES
PATH\DEPENDENCY.jar:META-INF/MANIFEST.MF

それは、 のように見える これは、私の依存関係の一部に、最終的なUber 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で[Build Artifact ...]をクリックすると、IDEA JARファイルが取得されます。しかし、私は同じエラーになります...

私はSBTを初めて使用しますが、IntelliJ IDEをあまり試していません。

ありがとう。

83
Yves M.

最後に、IntelliJ IDEAの使用を完全にスキップして、グローバルな理解におけるノイズの生成を回避します:)

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

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

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

Assembly.sbtファイルに sbt-Assemblyplugin を追加しました。太い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に触発された

% および %% の意味

これで、/ 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タスクを実行する方法?

133
Yves M.

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

Uber JAR/Fat JAR:すべての外部ライブラリ依存関係を含むJARファイル。

  1. IntelliJ IdeaにSBT Assemblyプラグインを追加する

    Plugin sbt Path

    ProjectName/project/target/plugins.sbtファイルに移動し、この行を追加しますaddSbtPlugin("com.eed3si9n" % "sbt-Assembly" % "0.12.0")

  2. Build.sbtにMerge、DiscardおよびDo Not Add戦略を追加する

    Build sbt Path

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

    マージ戦略:ライブラリのバージョンに関する2つのパッケージに競合がある場合、どちらをUber JARにパックするか。
    戦略の破棄:Uber JARにパッケージ化したくないファイルをライブラリから削除します。
    戦略を追加しない:Uber JARにパッケージを追加しないでください。
    例:spark-coreはSparkクラスターに既に存在するため、これを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

38
Ajay Gupta

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の作成時に発生した競合を解決するために使用されます。

16
ARMV