繁体   English   中英

如何在 IntelliJ IDEA 中使用 SBT 构建 Uber JAR(Fat JAR)?

[英]How to build an Uber JAR (Fat JAR) using SBT within IntelliJ IDEA?

我正在使用 SBT(在 IntelliJ IDEA 中)构建一个简单的 Scala 项目。

我想知道构建Uber JAR文件(又名 Fat JAR、Super JAR)的最简单方法是什么。

我目前正在使用 SBT,但是当我将 JAR 文件提交到Apache Spark 时,出现以下错误:

线程“main”中的异常 java.lang.SecurityException:Manifest 主要属性的签名文件摘要无效

或者在编译期间出现这个错误:

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 IDEA 中单击“ Build Artifact... ”时,我得到一个 JAR 文件。 但我最终遇到了同样的错误......

我是 SBT 的新手,对 IntelliJ IDE 没有太多的尝试。

谢谢。

最后,我完全跳过使用 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 中包含依赖项(这些库已经包含在我的工作人员中)

注意: 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 任务?

在 IntelliJ Idea 中构建 Uber JAR/Fat JAR 的 3 步过程:

Uber JAR/Fat JAR :包含所有外部库依赖项的 JAR 文件。

  1. 在 IntelliJ Idea 中添加 SBT Assembly 插件

    插件 sbt 路径

    转到ProjectName/project/target/plugins.sbt文件并添加这一行addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")

  2. 在 build.sbt 中添加合并、丢弃和不添加策略

    构建 sbt 路径

    转到ProjectName/build.sbt文件并添加 Uber JAR 打包策略

    合并策略:如果关于一个库版本的两个包存在冲突,那么在 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"

    如果我们不想将 spark-core 添加到我们的 Uber JAR 文件中,因为它已经在我们的 clutser 上,所以我们在它的库依赖项的末尾添加% "provided"

  3. 构建 Uber JAR 及其所有依赖项

    sbtassembly

    在用于构建包的终端类型sbt assembly


瞧!!! Uber JAR 构建完成。 JAR 将在ProjectName/target/scala-XX

罐装

将以下行添加到您的项目/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
}

Assembly合并策略用于解决创建fat jar时发生的冲突。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM