scala - sbt 组件,包括我的 jar

标签 scala apache-spark sbt

我想构建一个我的代码的“胖” jar 。我主要了解如何执行此操作,但我使用的所有示例都使用 jar 不是本地的想法,并且我不确定如何将我构建的 scala 代码使用的另一个 JAR 包含到我的组装 jar 中。就像我必须包含的这个 JAR 位于哪个文件夹中?

通常,当我使用 Spark-shell 运行当前代码作为测试时,它看起来像这样:

spark-shell --jars magellan_2.11-1.0.6-SNAPSHOT.jar -i st_magellan_abby2.scala 

(jar 文件与 .scala 文件位于同一路径中)

现在我想构建一个具有相同功能并包含 SNAPSHOT.jar 文件的 build.sbt 文件?

name := "PSGApp"
version := "1.0"
scalaVersion := "2.11.8"

resolvers += "Spark Packages Repo" at "http://dl.bintray.com/spark-packages/maven"

//provided means don't included it is there.  already on cluster?

libraryDependencies ++= Seq(
    "org.apache.spark" %% "spark-core" % "2.2.0" % "provided",
    "org.apache.spark" %% "spark-sql" % "2.2.0" % "provided",
    "org.apache.spark" %% "spark-streaming" % "2.2.0" % "provided",
    //add magellan here somehow?

)

那么我应该将 jar 放在 SBT 项目文件夹结构中的哪里,以便在运行 sbt assembly 时将其拾取?它在 main/resources 文件夹中吗?引用手册说的是“要包含在主 jar 中的文件”去哪里?

我应该在库依赖项中放入什么,以便它知道添加特定的 jar 而不是到互联网上获取它?

最后一件事,我还在测试代码中进行了一些导入,但现在我将此代码放入一个附加有 def main 的对象中,这些导入似乎不起作用。

我有这样的事情:

导入 sqlContext.implicits._ 就在上面的代码中,它将像这样使用:

val sqlContext = new org.apache.spark.sql.SQLContext(sc)

import sqlContext.implicits._
import org.apache.spark.sql.functions.udf

val distance =udf {(a: Point, b: Point) => 
   a.withinCircle(b, .001f);  //current radius set to .0001
}

我不确定是否可以将这些导入保留在 def main 中?或者我必须以某种方式将它们移到其他地方? (我猜仍在学习 scala 并争论范围界定)。

最佳答案

一种方法是在本地使用程序集插件 ( https://github.com/sbt/sbt-assembly ) 和 publishLocal 来构建 fat jar。将生成的 jar 存储到本地 ivy2 缓存中

这将使它可以根据该项目中的 build.sbt 设置包含在您的其他项目中,例如:

name := "My Project"
organization := "org.me"
version := "0.1-SNAPSHOT"

将在本地以 "org.me" %% "my-project" % "0.1-SNAPSHOT" 的形式提供 SBT 将在尝试从外部存储库下载之前搜索本地缓存。

但是,这被认为是不好的做法,因为只有最终项目才应该是一个 fat-jar。你永远不应该将其中之一作为依赖项(很多令人头痛的事情)。

如果 PGapp 中包含库,则没有理由将 magellan 项目制作为 fat-jar。只需publishLocal,无需汇编

另一种方法是使项目作为代码而不是库相互依赖。

lazy val projMagellan = RootProject("../magellan")
lazy val projPSGApp = project.in(file(".")).dependsOn(projMagellan)

这使得 projPSGApp 中的编译成为 projMagellan 中的 tigger 编译。

但这取决于您的用例。

只是不要陷入必须手动管理 .jar 的情况

另一个问题:

import sqlContext.implicits._应始终包含在需要数据帧操作的范围内,因此您不应将该导入放在标题中的其他导入附近


更新

根据评论中的讨论,我的建议是:

  • 获取麦哲伦存储库

git clone <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7a1d130e3a1d130e120f1854191517" rel="noreferrer noopener nofollow">[email protected]</a>:harsha2010/magellan.git

  • 创建一个要处理的分支,例如。

git checkout -b new-stuff

  • 更改您想要的代码
  • 然后更新版本号,例如。

version := "1.0.7-SNAPSHOT"

  • 本地发布

sbt publishLocal

您会看到类似的内容(一段时间后):

[info] published ivy to /Users/tomlous/.ivy2/local/harsha2010/magellan_2.11/1.0.7-SNAPSHOT/ivys/ivy.xml

  • 转到您的其他项目
  • 更改build.sbt包括

"harsha2010" %% "magellan" % "1.0.7-SNAPSHOT"在你的libraryDependencies

现在您对您的库有了一个很好的(临时)引用。

您的 PSGApp 应构建为 fat jar 程序集以传递给 Spark

sbt clean assembly

这将拉入自定义构建 jar

如果 magellan 项目中的更改对世界其他地方有用,您应该推送更改并创建拉取请求,以便将来您可以只包含此库的最新版本

关于scala - sbt 组件,包括我的 jar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49825081/

相关文章:

scala - `super` 是否静态绑定(bind)在类中?

spring - 如何在 Scala 中填充 Wicket @SpringBeans?

apache-spark - VectorAssembler 仅输出到 DenseVector?

scala - IntelliJ : Exception in thread "main" java. lang.NoClassDefFoundError: org/apache/spark/sql/types/DataType

scala - 如何改进 "nested Try.. match "的代码?

scala - 我可以在 Akka Actor 中安全地创建线程吗?

apache-spark - Graph 在 Spark 3.0+ 的 pyspark 上可用

apache-spark - 错误 SparkContext 无法在 Apache Spark 2.1.1 中添加文件

scala - SBT 未解决 Squeryl 依赖关系

scala - 如何拥有具有多个 Scala 版本的 SBT 子项目?