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

68de4m5k  于 2022-12-26  发布在  IntelliJ IDEA
关注(0)|答案(3)|浏览(265)

我正在使用SBT(在IntelliJ IDEA中)构建一个简单的Scala项目。
我想知道构建Uber JAR文件(又名Fat JAR、Super JAR)的最简单的方法是什么。
我目前正在使用SBT,但是当我将JAR文件提交到Apache Spark时,我收到以下错误:
线程"main"中出现异常java. lang。清单主属性的签名文件摘要无效
或编译时出现以下错误:
java.lang.RuntimeException:重复数据删除:在以下文件中找到不同的文件内容:
路径\依赖关系. jar:元信息/依赖关系
路径\依赖. jar:元信息/清单. MF
这看起来像是因为我的一些依赖项包括签名文件(META-INF),需要在最终的Uber JAR文件中删除这些文件。
我试着像这样使用sbt-assembly插件:
/项目/程序集. sbt

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

/项目/插件. sbt

logLevel := Level.Warn

/构建. 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没有太多的经验。
谢谢。

efzxgjgh

efzxgjgh1#

最后,我完全跳过使用IntelliJ IDEA,以避免在我的全局理解中产生噪音:)
我开始阅读official SBT tutorial
我使用以下文件结构创建了我的项目:

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")        
  )

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"意味着在最终的fat JAR中不包含依赖项(那些库已经包含在我的workers中了)
  • 注意 *:META-INF将丢弃inspired by this answser
  • 注 *:%%%的含义

现在我可以通过在我的**/my-project**根文件夹中运行以下命令来使用SBT(how to install it)构建我的胖JAR:

sbt assembly

我的fat JAR现在位于新生成的**/target**文件夹中:

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

对于那些希望在IntelliJ IDE中嵌入SBT的用户:How to run sbt-assembly tasks from within IntelliJ IDEA?

9njqaruj

9njqaruj2#

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

优比罐/胖罐:包含所有外部库依赖项的JAR文件。

1.在IntelliJ Idea中添加SBT汇编插件

转到项目名称/项目/目标/插件.sbt文件并添加此行addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
1.在build.sbt中添加合并、丢弃和不添加策略

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

**Merge Strategy:**如果两个包在库的版本上有冲突,那么在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"
1.构建Uber JAR及其所有依赖项

在终端类型sbt assembly中,用于构建程序包
瞧!!!Uber JAR构建完成。JAR将位于项目名称/target/scala-XX

n3ipq98p

n3ipq98p3#

将以下行添加到您的项目/plugins.sbt

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

将以下内容添加到您的构建.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时出现的冲突。

相关问题