文档

§Scala 3 迁移指南

本指南适用于将 Play 应用程序从 Scala 2 迁移到 Scala 3,并要求您的应用程序已在至少 Play 2.9(基于 Akka / Akka HTTP)或 Play 3.0(基于 Pekko / Pekko HTTP)上运行。

根据您的代码库,将现有 Play 应用程序迁移到 Scala 3 可能是一项艰巨的任务。我们强烈建议您首先 迁移到 Play 2.9 或 3.0,同时保留在 Scala 2.13 上。这种方法确保一切按预期运行。之后,您可以过渡到 Scala 3。

§一般

除了本页面提到的迁移步骤外,这些步骤涵盖了将 Play Framework 应用程序迁移到 Scala 3 所需的迁移步骤,还有一些通用的 Scala 3 资源,您需要遵循这些资源来将您的代码库迁移到 Scala 3

§在您的项目中设置 scalaVersion

Scala 和 Java 用户都必须配置 sbt 以使用 Scala 3。即使您的项目中没有 Scala 代码,Play 本身也使用 Scala,并且必须配置为使用正确的 Scala 库。

要在 sbt 中设置 Scala 版本,只需设置 scalaVersion 键,例如

scalaVersion := "3.3.3"

重要的是要强调,Play 专门支持 Scala LTS(长期支持) 版本。因此,任何介于 Scala 3.3 LTS 和后续 LTS 版本之间的 Scala 版本都不会得到 Play 的官方支持。但是,使用这些 Scala 版本与 Play 仍然是可行的。您可能对“Scala 3 兼容性故事”和 Scala 3.3 版本博客文章 感兴趣。

§将 Scala 3 与 Akka HTTP 10.5 或更高版本一起使用

本节仅适用于 Play 2.x,不适用于 Play 3.x。

如 Play 2.9 亮点所述,Play 2.9 继续提供 Akka 2.6 和 Akka HTTP 10.2,尽管有更新的版本可用。

然而,Akka HTTP 10.2 并未提供 Scala 3 的构件;只有 Akka HTTP 10.5 引入了它们。如果您希望在 Akka HTTP 中使用这些原生 Scala 3 构件,因此想要升级到 Akka HTTP 10.5 或更高版本,您可以借助我们的 Play ScalaPlay Java 更新指南来实现,这些指南还提供了有关调整哪些设置以在 Scala 3 中使用 Akka HTTP 10.5 或更高版本的说明。我们还强烈建议您查看

§某些测试需要 running() 包装器

§使用 specs2

specs2 的 Around 特性 利用了 Scala 的 DelayedInit,它 已在 Scala 3 中被弃用(实际上并没有删除,只是不再起作用)。不幸的是,Scala 3 中没有 DelayedInit 的替代品。因此,当 使用 specs2 编写测试 时,如果使用了

我们不得不找到一个解决方案,避免让用户完全重构他们的测试。我们想出的解决方案是在 running() 方法中包装测试,因为我们认为这是迁移这些测试最简单的方法,不会让迁移成本过高。例如,对于 WithApplication,类似于

"testing some logic" in new WithApplication {
  // <test code>
}

的代码现在需要写成

"testing some logic" in new WithApplication {
  override def running() = {
    // <test code>
  }
}

使用包装方法的一个优势是,我们让它在 Scala 2 中也能工作,因此,即使您将 Scala 2 测试包装在 running() 中,它们也能运行,因此,这样的测试代码可以轻松地在 Scala 2/3 之间来回切换,并且测试在两种情况下都能工作(这可能有助于迁移)。

§使用 ScalaTest Plus Play

当使用 ScalaTest 编写测试 并使用 AppServerChromeFirefoxHtmlUnitInternetExplorerSafari 时,你需要将测试代码包装在 running() 方法中,以使其在 Scala 3 中正常工作。这是因为在幕后,ScalaTest 也使用了 DelayedInit,就像上一节中描述的那样。例如,当使用 App 时,类似以下的代码

"testing some logic" in new App(...) {
 // <test code>
}

需要转换为

"testing some logic" in new App(...) {
  override def running() = {
    // <test code>
  }
}

§字符串插值路由 DSL (sird) 导入

我们不得不将一些方法从 隐式类 play.api.routing.sird.UrlContext 中分离出来,使用 扩展方法 代替。
对你来说,这意味着如果你直接导入了 UrlContext

import play.api.routing.sird.UrlContext

现在你必须改为从 sird 包中导入所有内容,以确保扩展方法也被导入

import play.api.routing.sird._

§依赖关系图更改

如果你开始在你的 Play 应用程序中使用 Scala 3,Play specs2依赖项 将不再拉入 "org.specs2" %% "specs2-mock" 依赖项,因为它不再适用于 Scala 3。Play specs2 Scala 3 工件依赖于 "org.mockito" % "mockito-core" 来直接使用 Mockito,我们认为这是在撰写本文时切换现有测试代码的最佳选择。
你需要调整你的代码,例如,以下是如何使用 Mockito 的代码片段

import org.mockito.Mockito._
import org.mockito.ArgumentMatchers._

val userRepository = mock(classOf[UserRepository])
when(userRepository.roles(any[User])).thenReturn(Set(Role("ADMIN")))

下一步:模块目录


发现此文档中的错误?此页面的源代码可以在这里找到 这里。在阅读了 文档指南 后,请随时贡献拉取请求。有任何问题或建议要分享?请访问 我们的社区论坛,与社区进行交流。