【问题标题】:In build.sbt, dependencies in parent project not reflected in child modules在 build.sbt 中,父项目中的依赖项未反映在子模块中
【发布时间】:2019-04-26 00:54:49
【问题描述】:

我在 intellij idea 2017.1.6 ide 中为我的 spark scala 项目使用 SBT 1.8.0。我想创建一个父项目及其子项目模块。到目前为止,这就是我在 build.sbt 中的内容:

lazy val parent = Project("spark-etl-parent",file("."))
.settings(
name := "spark-etl-parent_1.0",
scalaVersion := "2.11.1",
libraryDependencies ++= Seq(
"org.apache.spark" %% "spark-streaming" % sparkVersion % "provided" 
"org.apache.spark" %% "spark-hive" % sparkVersion % "provided")
)

lazy val etl = Project("spark-etl-etl",file("etl"))
.dependsOn(parent)
.settings(
name := "spark-etl-etl_1.0",
version := "1.0",
scalaVersion := "2.11.1"
)

lazy val redshiftBasin = Project("spark-etl- 
redshiftBasin",file("redshiftBasin"))
.dependsOn(parent)
.settings(
name := "spark-etl-redshiftBasin_1.0",
version := "1.0",
scalaVersion := "2.11.1"
 )


lazy val s3Basin = Project("spark-etl-s3Basin",file("s3Basin"))
.dependsOn(parent)
.settings(
name := "spark-etl-s3Basin_1.0",
version := "1.0",
scalaVersion := "2.11.1"
)

现在我可以从父模块中的 spark-streaming 或 spark-hive 库依赖项中导入任何类,但无法在任何子模块中导入和使用它们。只有当我在任何子模块中明确地将它们指定为库依赖项时,我才能使用它们。

  1. 我正在使用 Maven 构建在 pom.xml 中寻找类似于依赖项标记的内容。
  2. 如果我为每个子模块使用单独的 build.sbt 会有什么不同吗?
  3. 此外,如果我在父配置中执行 .aggregate(etl),它会显示错误,因为稍后会声明 etl。但是,如果我在父级之前定义 etl,我将无法在 etl 配置中执行 .dependsOn(parent) 。

请帮助我解决这些问题。

【问题讨论】:

    标签: scala apache-spark module sbt


    【解决方案1】:

    我的多模块项目仅使用父项目来构建所有内容并将运行委托给“服务器”项目:

    lazy val petstoreRoot = project.in(file(".")).
      aggregate(sharedJvm, sharedJs, server, client)
      .settings(organizationSettings)
      .settings(
        publish := {}
        , publishLocal := {}
        , publishArtifact := false
        , isSnapshot := true
        , run := {
          (run in server in Compile).evaluated
        }
      )
    

    我在另一个文件中分组的设置(例如依赖项),例如:

      lazy val sharedDependencies: Seq[Def.Setting[_]] = Def.settings(libraryDependencies ++= Seq(
        "org.julienrf" %%% "play-json-derived-codecs" % "4.0.0"
       ...
        , "org.scalatest" %%% "scalatest" % scalaTestV % Test
    
      ))
    

    现在每个子模块只添加需要的内容,例如:

    lazy val server = (project in file("server"))
      .settings(scalaJSProjects := Seq(client))
      .settings(sharedSettings(Some("server"))) // shared dependencies used by all
      .settings(serverSettings)
      .settings(serverDependencies)
      .settings(jvmSettings)
      .enablePlugins(PlayScala, BuildInfoPlugin)
      .dependsOn(sharedJvm)
    

    您可以在这里找到整个项目:https://github.com/pme123/scala-adapters

    请参阅 project/Settings 文件以了解依赖项。

    【讨论】:

    • 感谢您的回答,但我只想在 build.sbt 中进行更改。我现在发现问题在于我给出的范围:“提供”,似乎它不支持传递依赖,只有当我们将范围指定为“编译”时,依赖才会传播给孩子。我仍然想知道即使范围是“提供”,是否可以将依赖项从父级传播到子级。
    • @SatishSrinivas 我的解决方案也仅适用于build.sbt。因为build.sbt 只是一个增强的Scala class
    • 谢谢,但我在 build.sbt 中做了类似的事情,但是当我在父项目定义中给出 .aggregate(子项目)时,它说无法解决:递归值子项目需求类型。是因为子项目是在父项目之后定义的还是因为sbt版本问题?
    • 我从来没有遇到过这个问题。根据消息,您可以为子项目设置类型,例如:lazy val server: Project = (project in file("server")).....
    • 感谢您的帮助。我想出了一种单独执行任务的方法。但我认为它会影响我们为子项目单独构建 jar 的时间。当我为子项目执行打包命令时,它只为 jar 提供来自子项目的类,而不是来自它所依赖的父类的 jar。构建一个带有组装的胖罐子是解决这个问题的唯一方法吗?
    【解决方案2】:

    dependsOn 中使用provided->provided 帮助我解决了类似的问题:

    比如:

    lazy val etl = Project("spark-etl-etl",file("etl"))
    .dependsOn(parent % "compile->compile;test->test;provided->provided")
    .settings(
    name := "spark-etl-etl_1.0",
    version := "1.0",
    scalaVersion := "2.11.1"
    )
    

    【讨论】:

      猜你喜欢
      • 2019-02-12
      • 1970-01-01
      • 2016-12-03
      • 2021-02-27
      • 1970-01-01
      • 1970-01-01
      • 2019-12-03
      • 1970-01-01
      • 2013-06-19
      相关资源
      最近更新 更多