【问题标题】:sbt: using local jar without breaking the dependenciessbt:在不破坏依赖关系的情况下使用本地 jar
【发布时间】:2016-05-13 03:38:33
【问题描述】:

我正在构建一个使用 Spark 和 Spark-mllib 的应用程序,build.sbt 将依赖项声明如下:

  3   libraryDependencies ++= Seq(
  4     "org.apache.spark" %% "spark-core" % "1.6.0" withSources() withJavadoc(),
  5     "org.apache.spark" %% "spark-mllib" % "1.6.0" withSources() withJavadoc()
  6     )

这很好用。现在我想更改 mllib 中的一些代码并使用 sbt 重新编译应用程序,这就是我所做的:

  1. 下载spark-1.6.0的源代码,修改mllib中的代码,重新编译成一个jar,名为spark-mllib_2.10-1.6.0.jar
  2. 将上述jar放入项目的lib目录中。
  3. 同样将spark-core_2.10-1.6.0.jar放到项目的lib目录下。
  4. 删除 build.sbt 文件中的 libraryDependencies 语句。
  5. 运行 sbt clean package

但是,由于缺少 spark-core 和 spark-mllib 运行所需的依赖项,因此无法编译,仅当 libraryDependencies 的语句写入 build.xml 文件时,sbt 才会自动管理依赖项。 sbt.

所以我将 libraryDependencies 的声明放回 build.sbt 中,希望 sbt 能够解决依赖问题,并且仍然使用本地 spark-mllib 而不是来自远程存储库的那个。但是,运行我的应用程序表明情况并非如此。

所以我想知道是否有办法在不手动解决依赖问题的情况下使用我的本地 spark-mllib jar?

更新: 我遵循了 Roberto Congiu 回答的第一种方法,并使用以下 build.sbt 成功构建了包:

  1 lazy val commonSettings = Seq(
  2   scalaVersion := "2.10.5",
  3   libraryDependencies ++= Seq(
  4     "org.apache.spark" %% "spark-core" % "1.6.0" withSources() withJavadoc(),
  5     "org.apache.spark" %% "spark-streaming" % "1.6.0" withSources() withJavadoc(),
  6     "org.apache.spark" %% "spark-sql" % "1.6.0" withSources() withJavadoc(),
  7     "org.scalanlp" %% "breeze" % "0.11.2"
  8   )
  9 )
 10 lazy val core = project.
 11   settings(commonSettings: _*).
 12   settings(
 13     name := "xSpark",
 14     version := "0.01"
 15   ) 
 16   
 17 lazy val example = project.
 18   settings(commonSettings: _*).
 19   settings(
 20     name := "xSparkExample",
 21     version := "0.01"
 22   ).
 23   dependsOn(core)

xSparkExample 包含一个调用 xSpark 的 KMeans 示例,xSpark 调用 spark-mllib 中的 KMeans 函数。这个 spark-mllib 是一个自定义的 jar,我把它放在 core/lib 目录中,以便 sbt 可以将它作为本地依赖项来获取。

但是,由于某种原因,运行我的应用程序仍然没有使用自定义的 jar。我什至使用find . -name "spark-mllib_2.10-1.6.0.jar" 来确保我的系统上不存在其他 jar。

【问题讨论】:

    标签: apache-spark sbt apache-spark-mllib


    【解决方案1】:

    一种方法是将您的自定义 mlib 作为非托管依赖项。 非托管依赖项放在一个目录中,SBT 将按原样拾取它们,因此您也有责任提供它们的依赖项。 您可以在此处阅读有关非托管依赖项的信息:​​http://www.scala-sbt.org/0.13/docs/Library-Dependencies.html

    所以,您可以尝试以下方法:

    1. 创建一个lib 目录并在那里添加您的自定义mlib jar。这是非托管库的默认位置,sbt 会自动拾取它
    2. 在您的 build.sbt 中,删除对 mlib 的引用,并添加其所有依赖项,这些依赖项在 pom 中列出:https://github.com/apache/spark/blob/master/mllib/pom.xml。您可以跳过具有测试范围的那些。

    另一种方法是拥有自己的 Maven 存储库(工件)来放置自定义工件,并首先从该存储库中提取 sbt。这样做的好处是其他人将能够构建代码并使用您的自定义 mlib 库。

    【讨论】:

    • 非常感谢。但我认为 unmanagedBase := baseDirectory.value / "custom_lib" 仅在我想使用 lib 以外的目录来托管我的自定义 jar 时使用?
    • 是的,对不起,这是我这边的错误复制和粘贴,我更正了。您不需要添加“custom_lib”,我想指向包含 mlib 的所有依赖项的 pom。
    • 我使用了第一种方法,但自定义 jar 似乎仍然没有被拾取,我已经用新的 build.sbt 文件更新了我的帖子。
    猜你喜欢
    • 2013-12-25
    • 2011-03-06
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多