在SBT 0.13中,scalaVersion是否仍然控制用于编译,运行和测试的scala版本?

时间:2014-03-21 06:06:08

标签: scala sbt

当我们将构建从12.4升级到13.1时,我观察到虽然构建指定了scalaVersion := "2.10.2",但是生成的存档(通过sbt-pack插件创建)包含scala-library-2.10.3.jar。快速检查确认12.4版本包含scala-library-2.10.2.jar。

似乎sbt 0.13包含一个将scala库视为正常依赖项的更改,其结果是如果项目依赖项是使用稍后的2.10.x版本的scala构建的,则该传递依赖项将“赢得”常春藤依赖项解决冲突解决方案,编译,测试和运行类路径将包含更高版本的scala库。

这是期望的行为,还是sbt 0.13中的错误?

如果是所需的行为,那么这是否意味着我必须使用机制来“强制/覆盖”冲突解决方案以使用我想要的scala库版本? (如果是这样,scalaVersion配置设置似乎有点无意义......)

这是一个非常极小的测试用例来说明行为:

test-proj/
  build.sbt
  project/
    build.properties

build.sbt:

scalaVersion := "2.10.2"
//scalaVersion := "2.10.3"

libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.3.0"
//libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.2.4"

build.properties:

sbt.version=0.13.1

Akka 2.2.4是针对scala 2.10.2构建的,因此启动sbt并运行“update”,“show update”,“show compile:dependencyClasspath”,“show test:dependencyClasspath”和“show runtime:dependencyClasspath” all在类路径上显示scala-library 2.10.2。

切换到针对scala 2.10.3构建的Akka 2.3.0,导致scala-library 2.10.3出现在所有类路径上,“show update”清楚地显示2.10.2被Ivy的冲突解决方案驱逐。

有趣的是(并且不一致),在两种情况下(通过sbt控制台命令)输入REPL会导致使用scala 2.10.2。

根据docs,在sbt 0.13

  

scalaVersion配置用于编译的Scala版本。默认情况下,sbt还会在此版本的Scala库中添加依赖项。

基于此,我希望上面的编译类路径在两种情况下都包含2.10.2。

然而,the release notes for 0.13

  

Scala依赖项(如scala-library和scala-compiler)现在可以通过正常的更新任务解决

至少解释了观察到的行为。

1 个答案:

答案 0 :(得分:8)

sbt 0.13.0更改

您写道:

  

似乎sbt 0.13包含了将scala库视为正常依赖项的更改,结果是如果项目依赖项是使用稍后的2.10.x版本的scala构建的,则该传递依赖项将" win&# 34;常春藤依赖解析冲突解决方案,编译,测试和运行类路径将包含更高版本的scala库。

sbt 0.13.0这个问题的变化有些矛盾。 Features, fixes, changes with compatibility implications部分说:

  
      
  • sbt不再覆盖依赖项中的Scala版本。这允许独立配置依赖于不同的Scala版本,并将Scala依赖项除了scala-library 视为正常依赖项。 但是,对于其他Scala库,它可能会导致除scalaVersion之外的解析版本。
  •   

Resolving Scala dependencies部分说:

  

Scala依赖项(类似于scala-library 和scala-compiler)现在可以通过正常的update任务解决。

(Eugene强调的重点)所以快速回答你的"这是期望的行为,还是sbt 0.13中的错误?"正如你已经回答的那样:在sbt 0.13.x中,这种行为似乎是有意的。 Akka 2.3.0依赖于scala-library 2.10.3,而Ivy已经驱逐scala-library 2.10.2而支持2.10.3。

dependencyOverrides

要解决此问题,您可以使用dependencyOverrides设置,如下所示:

dependencyOverrides += "org.scala-lang" % "scala-library" % scalaVersion.value

在:

sbt-so-22551430> show fullClasspath
[info] List(... Attributed(/Users/xxx/.sbt/0.13/boot/scala-2.10.3/lib/scala-library.jar) ...)

后:

sbt-so-22551430> show fullClasspath
[info] List(... Attributed(/Users/xxx/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.10.2.jar) ...)

这种行为是否合适?

你的问题不是这是否是设计,而是如果这是可取的。我认为当前的行为是相当令人惊讶的,并且sbt应该至少改进通知构建用户这种行为。并且可能将其默认的常春藤冲突管理策略更改为force() scalaVersion中指定的版本。以下是我创建的两个GitHub问题: