在提供的sbt构建文件中动态更改库依赖项等

时间:2016-06-28 15:00:52

标签: scala apache-spark sbt sbt-assembly

我们对scala应用程序使用了很多spark。如果我在本地测试我的库依赖项是:

  libraryDependencies += "org.apache.spark" % "spark-core_2.10" % "1.6.1",
 libraryDependencies += "org.apache.spark" % "spark-sql_2.10" % "1.6.1" ,

然而,我正在构建一个jar来部署我使用:

  libraryDependencies += "org.apache.spark" % "spark-core_2.10" % "1.6.1" % "provided",
libraryDependencies += "org.apache.spark" % "spark-sql_2.10" % "1.6.1" % "provided",

由于工作的性质,我们有时可能需要在尝试不同的事情时来回翻转几次。不可避免的是,在某些时候我忘记更改构建文件并最终浪费时间,这不是很多时间,而是足以促使我提出这个问题。

那么,有没有人意识到构建文件根据触发器更新提供的值的方法(不包括记住'做对了')?也许是一个读取测试或实时的配置选项?

提前致谢。

1 个答案:

答案 0 :(得分:4)

我刚刚在我的示例中使用两个不同的spark版本执行了动态构建。我需要根据具体情况使用两种不同的版本。

你可以用两种方式做到这一点。由于您需要以一种或另一种方式提供输入,因此您需要使用命令行参数。

1)自己使用build.sbt。

a)您可以使用名称" sparkVersion"来定义参数。

b)在build.sbt中读取该参数,(您可以在build.sbt中编写scala代码,并在构建时以任何方式将其编译为scala。)

c)执行如下的基于条件的依赖性。

val sparkVersion = Option(System.getProperty("sparkVersion")).getOrElse("default")

if(sparkVersion == "newer"){
    println(" newer one");
    libraryDependencies += "org.apache.spark" %% "spark-core" % "1.6.0" 
}else{
    println(" default one");
    libraryDependencies += "org.apache.spark" %% "spark-core" % "1.6.0" % "provided"
}

您可以随意使用所有构建选项。

2)使用build.scala文件。您可以在/project/build.scala中创建build.scala文件

你可以写下面的代码。

import sbt._
import Keys._

object MyBuild extends Build {  
  val myOptionValue = Option(System.getProperty("scalaTestVersion")).getOrElse("defaultValue")

  val depVersion = if(myOptionValue == "newer"){
    println(" asked for newer version" );
    "2.2.6"
  }else{
    println(" asked for older/default version" );
    "2.2.0"
  }

   val dependencies = Seq(
    "org.scalatest" %% "scalatest" % depVersion % "test"
  )

   lazy val exampleProject = Project("SbtExample", file(".")).settings(
    version       := "1.2",
    scalaVersion  := "2.10.4",
    libraryDependencies ++= dependencies
  )

}

在此之后,只需运行build命令,如下所示。

sbt clean compile -DsparkVersion = newer -DscalaTestVersion = newer

我已经为两者提供了构建命令。您可以选择其中一个并只提供一个选项。 如果您需要任何帮助,请写信给我。

要解决构建中的重复项,您可以在build.sbt中添加以下内容

mergeStrategy in assembly := {
  case m if m.toLowerCase.endsWith("manifest.mf")          => MergeStrategy.discard
  case m if m.toLowerCase.matches("meta-inf.*\\.sf$")      => MergeStrategy.discard
  case "log4j.properties"                                  => MergeStrategy.discard
  case "log4j-defaults.properties"                         => MergeStrategy.discard
  case m if m.toLowerCase.startsWith("meta-inf/services/") => MergeStrategy.filterDistinctLines
  case "reference.conf"                                    => MergeStrategy.concat
  case _                                                   => MergeStrategy.first
}

你会明白这是多么善良和神奇的事情。