SBT打包排除jar文件

15

我正在使用Java API的Spark,并需要一个单一的JAR文件,可以推送到群集中,但是该JAR文件本身不应包含Spark。 当然,部署作业的应用程序应包括Spark。

我希望:

  1. sbt run - 一切都应该被编译和执行
  2. sbt smallAssembly - 创建一个没有Spark的JAR
  3. sbt assembly - 创建一个包含所有内容(包括Spark)以便于部署的超级JAR。

我已经实现了1和3。 有什么方法可以完成2?我需要在我的build.sbt文件中添加哪些代码?

这个问题不仅与Spark相关,还与其他可能要排除的任何依赖项相关。


假设您使用其他库,如Scalaz和Dispatch。您希望将其包含在smallAssembly中还是排除在外? - Eugene Yokota
好问题。最好不要包含-smallAssembly中不需要部署到集群上的代码。 - user2843110
2个回答

31

"provided"配置

从库依赖中排除一个JAR文件的第一种选项是在库依赖上使用"provided"配置。 "provided"来自于Maven的provided作用域,定义如下:

这与compile非常相似,但表示您期望JDK或容器在运行时提供依赖项。例如,在为Java企业版构建Web应用程序时,将范围设置为provided的Servlet API和相关Java EE API依赖项,因为Web容器提供这些类。此作用域仅在编译和测试类路径上可用,并且不具有传递性。

由于您将代码部署到容器中(在这种情况下是Spark),与您的注释相反,您可能需要Scala标准库和其他库JAR文件(例如,如果使用了Dispatch)。 这不会影响runtest

packageBin

如果您只想要源代码,而没有Scala标准库或其他库依赖项,那么可以使用sbt中的packageBin构建。此打包的JAR文件可以与使用sbt-assembly的assemblyPackageDependency生成的仅依赖项JAR文件结合使用。

在汇编中排除的JAR文件

最后一种选择是使用excludedJars in assembly

excludedJars in assembly := {
  val cp = (fullClasspath in assembly).value
  cp filter {_.data.getName == "spark-core_2.9.3-0.8.0-incubating.jar"}
}

9

对于像我这样的初学者,只需将% Provided添加到Spark依赖项中即可将它们从uber-jar中排除:

libraryDependencies += "org.apache.spark" %% "spark-core" % "1.4.0" % Provided
libraryDependencies += "org.apache.spark" %% "spark-sql" % "1.4.0" % Provided

build.sbt文件中。

如果这样做,你将无法直接从IDE或sbt运行你的项目进行开发java.lang.NoClassDefFoundError: org/apache/spark/sql/SparkSession$ - FelipeKunzler
1
据我所知,在Intellij中,有一种配置选项可以下载具有提供的范围的JAR包。其他集成开发环境肯定也有类似的选项。 - Gaurav Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接