如何高效地使用 SBT、Spark 和“提供的”依赖项?

问题描述 投票:0回答:8

我正在 Scala 中构建 Apache Spark 应用程序,并使用 SBT 来构建它。事情是这样的:

  1. 当我在 IntelliJ IDEA 下进行开发时,我希望 Spark 依赖项包含在类路径中(我正在启动带有主类的常规应用程序)
  2. 当我打包应用程序(感谢 sbt-assemble)插件时,我确实希望 Spark 依赖项包含在我的 fat JAR 中
  3. 当我通过
    sbt test
    运行单元测试时,我希望 Spark 依赖项包含在类路径中(与 #1 相同,但来自 SBT)

为了匹配约束 #2,我将 Spark 依赖项声明为

provided
:

libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-streaming" % sparkVersion % "provided",
  ...
)

然后,sbt-assemble 的文档建议添加以下行以包含单元测试的依赖项(约束 #3):

run in Compile <<= Defaults.runTask(fullClasspath in Compile, mainClass in (Compile, run), runner in (Compile, run))

这给我留下了约束 #1 没有被填满,即我无法在 IntelliJ IDEA 中运行应用程序,因为 Spark 依赖项没有被拾取。

使用 Maven,我使用特定的配置文件来构建 uber JAR。这样,我将 Spark 依赖项声明为主配置文件(IDE 和单元测试)的常规依赖项,同时将它们声明为 fat JAR 打包的

provided
。请参阅https://github.com/aseigneurin/kafka-sandbox/blob/master/pom.xml

通过 SBT 实现这一目标的最佳方法是什么?

intellij-idea apache-spark sbt sbt-assembly
8个回答
25
投票

在 IntelliJ 配置中使用新的“包含具有“提供”范围的依赖项”。


19
投票

(用我从另一个渠道得到的答案来回答我自己的问题......)

为了能够从 IntelliJ IDEA 运行 Spark 应用程序,您只需在

src/test/scala
目录(
test
,而不是
main
)中创建一个主类。 IntelliJ 将获取
provided
依赖项。

object Launch {
  def main(args: Array[String]) {
    Main.main(args)
  }
}

感谢Matthieu Blanc指出这一点。


4
投票

您需要让 IntellJ 正常工作。

这里的主要技巧是创建另一个子项目,该子项目将依赖于主子项目,并将其提供的所有库都包含在编译范围内。为此,我将以下行添加到 build.sbt:

lazy val mainRunner = project.in(file("mainRunner")).dependsOn(RootProject(file("."))).settings(
  libraryDependencies ++= spark.map(_ % "compile")
)

现在我在 IDEA 中刷新项目并稍微更改以前的运行配置,以便它将使用新的 mainRunner 模块的类路径:

对我来说完美无缺。

来源:https://github.com/JetBrains/intellij-scala/wiki/%5BSBT%5D-How-to-use-provided-libraries-in-run-configurations


4
投票

对于运行 Spark 作业,您可以使用“提供的”依赖项:https://stackoverflow.com/a/21803413/1091436

然后您可以从

sbt
、Intellij IDEA 或其他任何东西运行该应用程序。

sbt
中的示例:

run in Compile := Defaults.runTask(fullClasspath in Compile, mainClass in (Compile, run), runner in (Compile, run)).evaluated,
runMain in Compile := Defaults.runMainTask(fullClasspath in Compile, runner in(Compile, run)).evaluated

2
投票

此处描述了基于创建另一个子项目以在本地运行项目的解决方案。 基本上,您需要使用以下内容修改

build.sbt

文件:


lazy val sparkDependencies = Seq( "org.apache.spark" %% "spark-streaming" % sparkVersion ) libraryDependencies ++= sparkDependencies.map(_ % "provided") lazy val localRunner = project.in(file("mainRunner")).dependsOn(RootProject(file("."))).settings( libraryDependencies ++= sparkDependencies.map(_ % "compile") )

然后使用“运行配置”下的 
Use classpath of module: localRunner

在本地运行新的子项目。

    


2
投票
[已过时] 请参阅新答案“在 IntelliJ 配置中使用新的‘包含具有“提供”范围的依赖项’。”回答。

添加

provided

依赖项以使用

IntelliJ
调试任务的最简单方法是:

右键单击
    src/main/scala
  • 选择 
  • Mark Directory as...
  • >
    Test Sources Root
    
    
    
  • 这告诉
IntelliJ

src/main/scala
视为测试文件夹,它将所有标记为
provided
的依赖项添加到任何运行配置(调试/运行)。

每次执行 SBT 刷新时,请重做这些步骤,因为 IntelliJ 会将文件夹重置为常规源文件夹。


0
投票


-2
投票

打开“项目结构”对话框(例如 ⌘;)。
  • 在对话框的左侧窗格中,选择模块。
  • 在右侧窗格中,选择感兴趣的模块。
  • 在对话框右侧的“模块”页面上,选择“依赖项”选项卡。
  • 在“依赖项”选项卡上,单击“添加”并选择“库”。
  • 在“选择库”对话框中,从 maven 中选择新库
  • 找到火花芯。前
  • org.apache.spark:spark-core_2.10:1.6.1
  • 利润
https://www.jetbrains.com/help/idea/2016.1/configuring-module-dependency-and-libraries.html?origin=old_help#add_existing_lib

© www.soinside.com 2019 - 2024. All rights reserved.