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

标签 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 库视为普通依赖项,因此,如果项目依赖项是使用更高版本的 scala 2.10.x 构建的,那么该传递依赖项将“赢得”ivy 依赖项解决冲突,编译、测试和运行类路径将包含更高版本的scala库。

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

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

这是一个极其简单的测试用例来说明该行为:

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

构建.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"

构建.属性:

sbt.version=0.13.1

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

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

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

根据docs ,sbt 0.13

The scalaVersion configures the version of Scala used for compilation. By default, sbt also adds a dependency on the Scala library with this version.

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

但是,the release notes for 0.13

Scala dependencies (like scala-library and scala-compiler) are now resolved via the normal update task

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

最佳答案

sbt 0.13.0 更改

你写道:

It appears that sbt 0.13 included a change to treat the scala libraries as normal dependencies, with the consequence that if a project dependency was built with a later 2.10.x version of scala then that transitive dependency will "win" the ivy dependency resolution conflict resolution, and the compile, test and run classpaths will contain the later version of scala libraries.

sbt 0.13.0 Changes 对此问题的注释有些矛盾。 Features, fixes, changes with compatibility implications部分说:

  • sbt no longer overrides the Scala version in dependencies. This allows independent configurations to depend on different Scala versions and treats Scala dependencies other than scala-library as normal dependencies. However, it can result in resolved versions other than scalaVersion for those other Scala libraries.

Resolving Scala dependencies部分说:

Scala dependencies (like scala-library and scala-compiler) are now resolved via the normal update task.

(尤金添加的强调)因此,快速回答您的“这是期望的行为,还是 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 += "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 至少应该在通知构建用户此行为方面有所改进。也许将其默认的 Ivy 冲突管理策略更改为 force() scalaVersion 中指定的版本。以下是我创建的两个 GitHub 问题:

关于scala - 在SBT 0.13中,scalaVersion是否仍然控制用于编译、运行和测试的scala版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22551430/

相关文章:

2.11 中的 Scala 脚本

java - 运行 sbt install-emulator 时出错

java - SBT SCALA java.lang.ClassNotFoundException : javax. mail.Authenticator

scala - 用于使用 Play/SBT 进行自定义测试配置的 javaOptions

sbt 控制台如何更新到最新的 Scala 版本?

以 _= 结尾的 Scala 方法

python - 列出数据湖中文件夹中的所有文件

scala - 如何在 Scala 中定义新的原始数据类型及其行为

python - 访问 WrappedArray 元素

scala - 适用于Scala SBT Akka Actor的application.conf