§Play 2.9 迁移指南
- 本指南适用于从 Play 2.8 迁移到 Play 2.9。请参阅 Play 2.8 迁移指南 以了解如何从 Play 2.7 升级。
- 如果您已完成本迁移指南,并希望继续将您的应用程序迁移到 Play 3.0(基于 Pekko 和 Pekko HTTP),请参阅 Play 3.0 迁移指南 获取更多说明。
§如何迁移
在启动 sbt
之前,请确保进行以下升级。
§Play 升级
在 project/plugins.sbt
中更新 Play 版本号
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.9.x")
其中 2.9.x
中的“x”是您要使用的 Play 的次要版本,例如 2.9.0
。
查看 Play 次要版本的发布说明 发布。
§sbt 升级
Play 2.9 仅支持 sbt 1.9 或更高版本。要更新,请更改您的 project/build.properties
,使其读取
sbt.version=1.9.6
在撰写本文时,1.9.6
是 sbt 1.x 系列中的最新版本,您可能也可以使用更新的版本。查看 sbt 的发布说明 发布 获取详细信息。
§最低要求的 Java 和 sbt 版本
Play 2.9 版本不再支持 Java 8,最低要求 Java 11。其他支持的 Java 版本包括 17 和 21。升级到 Play 2.9 时,强烈建议您考虑升级到至少 Java 17 LTS 版本。值得注意的是,在即将发布的 Play 2.x 版本(即 2.10 版本)中,我们可能会停止对 Java 11 的支持。
请注意,在 Java 17 和 Java 21 中使用自签名证书绑定 HTTPS 端口可能会导致问题。有关此问题的更多详细信息,请参阅 "Java 17 和 Java 21 中自签名证书生成失败"。
§Jetty ALPN Agent 已移除
由于 Java 11 是 Play 2.9 的最低要求 Java 版本,并且原生支持 ALPN,因此 Jetty ALPN Agent 现在不再严格要求。
如果您之前在 Play 应用程序中传递了 -javaagent:jetty-alpn-agent-*.jar
标志(可能通过 SBT_OPTS
环境变量),您现在需要移除这些标志。
§升级 Akka 和 Akka HTTP
如果您希望升级到 Akka 2.6 和 Akka HTTP 10.2 以上版本,您可以参考我们的 Play Scala 或 Play Java 更新指南。我们也强烈建议您查看
§API 变更
Play 2.9 包含多个 API 变更。与往常一样,我们遵循在移除现有 API 之前先弃用的策略。本节详细介绍了这些变更。
§Scala 2.12 支持已停止
Play 2.9 支持 Scala 2.13 和 Scala 3.3,但不再支持 2.12。Scala 3 需要一些额外的迁移步骤,您可以在我们的 Scala 3 迁移指南 中找到这些步骤。
§在项目中设置 scalaVersion
Scala 和 Java 用户都必须配置 sbt 以使用支持的 Scala 版本。即使您的项目中没有 Scala 代码,Play 本身也使用 Scala,并且必须配置为使用正确的 Scala 库。
要在 sbt 中设置 Scala 版本,只需设置 scalaVersion
键,例如
scalaVersion := "2.13.13"
Play 2.9 也支持 Scala 3
scalaVersion := "3.3.3"
重要的是要强调,Play 仅支持 Scala LTS(长期支持) 版本。因此,任何介于 Scala 3.3 LTS 和后续 LTS 版本之间的 Scala 版本都不会被 Play 官方支持。但是,您仍然可以使用这些 Scala 版本与 Play 一起使用。
如果您只有一个项目构建,那么此设置可以单独放在 build.sbt
中的一行。但是,如果您有多个项目构建,则必须在每个项目上设置 scala 版本设置。通常,在多项目构建中,您将有一些由每个项目共享的通用设置,这是放置设置的最佳位置,例如
def commonSettings = Seq(
scalaVersion := "2.13.13"
)
val projectA = (project in file("projectA"))
.enablePlugins(PlayJava)
.settings(commonSettings)
val projectB = (project in file("projectB"))
.enablePlugins(PlayJava)
.settings(commonSettings)
§重命名以实现更一致的方法名称
一些类和方法被重命名以增强不同 API 之间的一致性,尤其是用于添加、删除和清除数据的那些方法。
为了实现平滑迁移,旧方法现在已弃用,将在未来版本中删除。
在特质 play.api.i18n.MessagesApi
中重命名的方法
已弃用方法 | 新方法 |
---|---|
clearLang(result: Result) |
withoutLang(result: Result) |
在对象 play.api.mvc.Results
中重命名的方法
已弃用方法 | 新方法 |
---|---|
clearingLang(result: Result) |
withoutLang(result: Result) |
在 play.api.libs.typedmap.TypedMap
中重命名的方法
已弃用方法 | 新方法 |
---|---|
+ |
updated |
- |
removed |
以下类已重命名
已弃用类 | 新类 |
---|---|
HttpExecutionContext |
ClassLoaderExecutionContext |
HttpExecution |
ClassLoaderExecution |
§已弃用的 API 已被删除
在 Play 2.9 中删除了许多在早期版本中已弃用的 API。如果您仍在使用它们,我们建议您在升级到 Play 2.9 之前迁移到新的 API。查看 Javadoc 和 Scaladocs 以获取迁移说明。有关更多信息,请参阅 Play 2.8 的迁移指南。
§更改 CSP 报告类型
根据 w3.org 规范,CSP 报告中有一些更改。从 Play 2.9 开始,字段 lineNumber
和 columnNumber
是 Long 类型。如果您的实现基于这些字段是字符串,Play 将回退到将它们从字符串解析为 Long,并且仅在解析失败时才会抛出错误。但是,建议使用数字类型而不是字符串,因为这可能会在 CSP3 发布时发生更改。
§Request.asJava
现在始终将主体包装在 RequestBody
中
使用 asJava
方法将 Scala 请求转换为 Java 请求时,生成的 Java 请求现在将始终将主体包装在 Http.RequestBody
类中。此更改确保一致性,因为在 Play Java 中,请求主体始终包装在此类中。
以前,此转换未完全执行,并且转换后的 Java 请求可能直接包含 Scala 请求主体,而不会包装在 Http.RequestBody
中。
但是,需要注意的是,尽管将请求主体包装在RequestBody
类中,但在将 Scala 请求转换为 Java 请求时,主体本身不会自动转换为其 Java 等效项。例如,如果 Scala 请求包含一个play.api.mvc.RawBuffer
,它不会被转换为其 Java 等效项play.mvc.Http.RawBuffer
。类似地,Scala AnyContentAsEmpty
不会被转换为 java.util.Optional.empty()
(这是 Play Java 中空主体的等效项)。因此,像 request.asJava.body().asRaw()
、.asJson()
等辅助方法可能无法按预期工作。
要检索任何存储的 Play Scala 主体对象,可以使用 request.asJava.body().as(classOf[Object])
。
§从 Java 持久性 API 迁移到 Jakarta 持久性 API
为了最终支持 Hibernate ORM 6+ 和 EclipseLink 3+,Play 需要将其JPA 模块迁移到Jakarta 持久性 API。要迁移代码,首先必须在 build.sbt
中的 libraryDependencies
中升级 Hibernate 或 EclipseLink。然后,按照以下步骤调整 Java 文件中的导入内容
从
import javax.persistence.*;
到
import jakarta.persistence.*;
此外,请更新 persistence.xml
,如下所示
从
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
...
到
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
version="3.0">
...
此外,请更新所有配置参数,将前缀 javax.persistence
替换为 jakarta.persistence
。例如
从
<property name="javax.persistence.jdbc.driver" value="..."/>
到
<property name="jakarta.persistence.jdbc.driver" value="..."/>
此外,我们收到了报告,表明可能需要(如果适用)在配置中将提供程序从
<provider>org.hibernate.ejb.HibernatePersistence</provider>
更改为
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
以确保 Hibernate 与 Play 2.9 正确配合。
虽然使用了
version="3.0"
和persistence_3_0.xsd
,但此 XML 声明对于最新 Jakarta 持久性 3.1 是正确的。这是因为在 Jakarta 持久性 3.1 中,persistence.xml
架构保持不变。为了避免重复,3.0 架构被重用于版本更新:https://jakarta.ee/xml/ns/persistence/
§Play 2.9 中当前不支持 JPA Bean 验证
需要注意的是,Play 2.9 当前不支持 Bean 验证。有关更多信息,请参阅此处提供的详细信息。
§JNotify 监视服务不再可用
JNotifyFileWatchService
已从play-file-watch
中删除,因此
play.dev.filewatch.FileWatchService.jnotify
不再可用作 PlayKeys.fileWatchService
的值。
§从 PlayKeys
中删除了一些设置
设置 playOmnidoc
、playDocsName
、playDocsModule
和 playDocsJar
已从 PlayKeys
中删除。这些设置不再使用,因为在相当长的一段时间内,无法在本地运行 Play 文档。
§命名空间变更: org.fluentlenium
至 io.fluentlenium
FluentLenium 已将其命名空间从 org.fluentlenium
迁移到 io.fluentlenium
。因此,您可能需要相应地更新您的导入。
§配置变更
本节列出了配置中的变更和弃用。
§应用程序密钥强制执行最小长度
应用程序密钥配置 play.http.secret.key
现在在所有模式(prod、dev 和 test)中强制执行最小长度检查。如果未达到最小长度,则会抛出错误,导致配置无效并阻止应用程序启动。
最小长度取决于用于签署会话或闪存 cookie 的算法,可以通过配置键 play.http.session.jwt.signatureAlgorithm
和 play.http.flash.jwt.signatureAlgorithm
设置。默认情况下,这两个配置都使用 HS256
算法,要求密钥至少为 256 位(32 字节)。对于 HS384
,最小大小为 384 位(48 字节),对于 HS512
,最小大小为 512 位(64 字节)。
当发生此错误时,它会提供详细的解决信息。
Configuration error [
The application secret is too short and does not have the recommended amount of entropy for algorithm HS256 defined at play.http.session.jwt.signatureAlgorithm.
Current application secret bits: 248, minimal required bits for algorithm HS256: 256.
To set the application secret, please read https://playframework.com/documentation/latest/ApplicationSecret
]
您可以通过确保密钥包含所需的位数/字节数来解决此错误。例如,您可以使用 head -c 32 /dev/urandom | base64
生成至少包含 32 字节完全随机输入的密钥,或者您可以使用 playGenerateSecret
或 playUpdateSecret
生成应用程序密钥。
§新的 Logback 配置格式
从 1.3 版本开始,Logback 使用新的规范格式来表示其配置文件。Play 已升级到最新的 Logback 版本,因此您应该将 Logback 配置文件更新到这种新格式。您可以使用 Logback 团队提供的 在线翻译器 轻松完成此操作。使用您的 GitHub 帐户登录,然后复制并粘贴您现有的 Logback 配置以进行转换。
虽然旧的配置格式仍然有效,但建议您现在升级,因为该过程很简单。
此外,Play 特定的 coloredLevel
转换器已被弃用。Logback 已经提供内置的着色模式 一段时间了。因此,请从您的 Logback 配置文件中删除以下行
<conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel" />
相反,在您的模式中用 %highlight(%-5level)
替换 %coloredLevel
<!-- Deprecated: -->
<pattern>... %coloredLevel ...</pattern>
<!-- Recommended: -->
<pattern>... %highlight(%-5level) ...</pattern>
§已删除 play.akka.config
设置
在引导 Actor 系统时,Akka 会从其提供的“根”配置中的硬编码 akka
前缀中查找其设置。此行为是 Akka 的固有特性,与 Play 无关。
默认情况下,Play 指示 Akka 直接从应用程序配置根路径加载其 Actor 系统设置。因此,您通常在 application.conf
中的 akka.*
命名空间下配置 Play 的 Actor 系统。
直到 Play 2.9,您可以选择使用 play.akka.config
配置来指定 Play 获取其 Akka 设置的备用位置。如果您打算将 akka.*
设置用于单独的 Akka Actor 系统,这将很有用。但是,此配置已因两个主要原因而被删除
-
缺乏文档:
play.akka.config
设置没有得到很好的记录。文档没有说明,即使您设置了play.akka.config = "my-akka"
,配置根路径中的akka.*
设置仍将作为回退加载。这意味着对akka.*
配置所做的任何更改也会影响在my-akka.akka.*
中定义的 Actor 系统。因此,这两个 Actor 系统无法独立运行,play.akka.config
所暗示的承诺(启用仅将akka.*
用于另一个 Akka Actor 系统)没有实现。 -
配置期望:Play 预计 Actor 系统配置将位于
akka.*
命名空间中,并在该前缀内设置各种配置以确保无缝运行。如果您要为 Play 使用完全不同的 Actor 系统,您的应用程序可能会无法正常运行。
由于这些考虑因素,从 Play 2.9 开始,akka.*
前缀专门用于 Play 的 Akka 配置,无法更改。您仍然可以实现自己的 Actor 系统,但必须确保它们不会从根路径中的 Play 的 akka
前缀读取其配置。
§直接在 akka.*
配置中定义的调度程序将不再自动加载
作为删除 play.akka.config
配置的副作用,不再可以在 akka.*
配置键内直接定义调度程序,因为它们将不再由默认 Actor 系统自动加载。相反,您将遇到类似以下的异常
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[ConfigurationException: Dispatcher [my-context] not configured]]
...
Caused by: akka.ConfigurationException: Dispatcher [my-context] not configured
...
您现在必须
- 在查找调度程序时指定
akka.*
前缀(例如,lookup("akka.my-context")
)或 - 将
my-context
调度程序配置直接放在配置的根目录中,或 - 将调度程序移到不同的子键中,并从那里查找它们(例如,在配置
contexts.my-context { ... }
和lookup("contexts.my-context")
中)。
实际上,Play 2.9 及更高版本的行为是正确的:调度程序不应该从 akka.*
键中自动读取。这在普通的 Akka 应用程序中也不起作用。能够将调度程序放在 akka.*
键中只是 play.akka.config
实现错误的 Play 特定副作用。
§默认值变更
Play 使用的几个默认值已更改,这可能会影响您的应用程序。本节概述了这些默认值的变更。
§在 Java 17 和 Java 21 中生成自签名证书失败
在绑定 HTTPS 端口的过程中,Play 通常会生成一个自签名证书作为默认操作。但是,当使用 Java 17 时,此操作可能会导致以下异常
java.lang.IllegalAccessError: class com.typesafe.sslconfig.ssl.FakeKeyStore$ (in unnamed module @0x68c8dd0e) cannot access class sun.security.x509.X509CertInfo (in module java.base) because module java.base does not export sun.security.x509 to unnamed module @0x68c8dd0e (FakeKeyStore.scala:89)
com.typesafe.sslconfig.ssl.FakeKeyStore$.createSelfSignedCertificate(FakeKeyStore.scala:89)
com.typesafe.sslconfig.ssl.FakeKeyStore$.generateKeyStore(FakeKeyStore.scala:79)
play.core.server.SelfSigned$.x$1$lzycompute(SelfSigned.scala:24)
play.core.server.SelfSigned$.x$1(SelfSigned.scala:23)
play.core.server.SelfSigned$.sslContext$lzycompute(SelfSigned.scala:23)
play.core.server.SelfSigned$.sslContext(SelfSigned.scala:23)
play.core.server.SelfSignedSSLEngineProvider.sslContext(SelfSigned.scala:36)
...
为了在标准 Play 应用程序设置中规避此异常,测试的 HTTPS 端口绑定已默认禁用。值得注意的是,测试中 HTTPS 端口的解绑是回归到旧的行为,因为 HTTPS 端口绑定在我们禁用它之后在早期的 Play 版本中被无意地激活了。
如果您希望在使用 Play 生成的自签名证书时对 HTTPS 端口进行测试,则需要针对 Java 17 进行变通方案。它涉及在 Java 17 命令行中添加一个 --add-export
标志。此外,在测试执行期间,必须分叉一个新的 Java 虚拟机 (JVM) 实例
Test / javaOptions += "--add-exports=java.base/sun.security.x509=ALL-UNNAMED"
// Test / fork := true // This is the default behavior in Play; a reminder in case the setting was changed to false previously
或者,您可以设置 JAVA_TOOL_OPTIONS
环境变量
export JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS --add-exports=java.base/sun.security.x509=ALL-UNNAMED";
不幸的是,上述变通方案对于 Java 21 不够。在这种情况下,您可能会遇到以下异常
java.lang.NoSuchMethodError: 'void sun.security.x509.X509CertInfo.set(java.lang.String, java.lang.Object)' (FakeKeyStore.scala:92)
com.typesafe.sslconfig.ssl.FakeKeyStore$.createSelfSignedCertificate(FakeKeyStore.scala:92)
com.typesafe.sslconfig.ssl.FakeKeyStore$.generateKeyStore(FakeKeyStore.scala:79)
play.core.server.SelfSigned$.x$1$lzycompute(SelfSigned.scala:24)
play.core.server.SelfSigned$.x$1(SelfSigned.scala:23)
play.core.server.SelfSigned$.sslContext$lzycompute(SelfSigned.scala:23)
play.core.server.SelfSigned$.sslContext(SelfSigned.scala:23)
play.core.server.SelfSignedSSLEngineProvider.sslContext(SelfSigned.scala:36)
...
截至目前,在 Play 中使用 Java 21 生成自签名证书不可行。建议继续使用 Java 17 来完成此目的。您可以通过以下 GitHub 链接 监控此问题的解决情况。
通常,自签名证书不适合用于提供网站。有关更全面的 HTTPS 配置信息,请参阅 "配置 HTTPS" 或 "在生产环境中使用 Play"。
§AnyContent
体解析器处理空主体的方式变更
如果您使用 AnyContent
体解析器,例如 Play Scala 中的 parse.anyContent
或 Play Java 中的 @BodyParser.Of(BodyParser.AnyContent.class)
,请注意,当体解析过程产生空主体时,行为已更新。在 Play Scala 中,请求主体现在将被分配给 AnyContentAsEmpty
,而在 Play Java 中,它将被设置为 Optional.empty()
。
以前,空主体与基于 Content-Type
标头的特定“空”类型相关联。例如,如果 Play 将空主体解析为原始缓冲区,则请求将包含一个大小为零的 RawBuffer
对象。
§处理不正确的百分比编码 URI 字符
自 akka-http 10.2.0 以来,akka-http 会立即将不正确的百分比编码 URI 字符视为 400 错误请求。这种行为不会给 Play 机会处理错误。为了确保两个 HTTP 后端之间的兼容性,我们使 netty 的行为方式相同 - 在解析不正确的百分比编码字符时不通过错误处理程序。这种方法旨在最大限度地提高兼容性,以防一个后端被另一个后端替换。
§Caffeine 有一个新的默认值,由 play.cache.caffeine.defaults.maximum-size
定义。
如果您的应用程序随着时间的推移向缓存添加了许多项目,使用基于 Caffeine 的缓存,JVM 最终可能会由于 内存不足
错误而崩溃。我们正在将 10,000 定义为 Caffeine 配置的项目默认值。
§Caffeine 现在在内部使用 Play 的默认调度器
Caffeine 默认情况下在内部使用的调度器现在是 Play 的默认调度器。在 Play 2.9.0 之前,使用的是 Java 的通用池 (ForkJoinPool.commonPool()
)。
您可以通过配置 play.cache.dispatcher
更改使用的调度器,甚至可以为不同的缓存设置不同的执行器,如 Scala 缓存 API 和 Java 缓存 API 中所述。
§测试服务器现在使用随机端口
在使用 Play Java、Play Scala specs2 或 ScalaTest + Play 编写功能测试时,如果您没有明确指定测试服务器运行的端口,它现在将默认使用随机端口,而不是之前的默认端口 19001
。此更改旨在促进并行运行测试。除了提供明确的端口之外,您还可以设置系统属性 testserver.port
(例如,设置为 19001
以启用之前的行为)。
重要的是,在使用随机端口时,您需要在测试中检索正确的端口。除了使用 running(TestServer(...))(block(..))
之外,您现在还可以使用新引入的方法 runningWithPort(TestServer(...))(port => block(..))
,该方法将实际使用的端口作为参数提供。
§测试服务器不再默认绑定 HTTPS 端口
除了上一节中讨论的新随机端口行为之外,测试服务器不再默认绑定 HTTPS 端口。但是,您可以通过传递 testserver.httpsport
系统属性重新启用此行为。如果绑定了 HTTPS 端口,将使用自签名证书。
§依赖关系图更改
play-jdbc-api
工件不再依赖于 play
核心工件。
§更新的库
Play 2.9 升级了我们自己的库的以下内容
依赖项 | 从 | 到 |
---|---|---|
Play 文件监视 | 1.1.16 | 1.2.0 |
Play JSON | 2.8.2 | 2.10.0 |
Play WS | 2.1.11 | 2.2.0 |
Twirl | 1.5.1 | 1.6.0 |
除了更新我们自己的库的更新版本之外,许多其他重要的第三方依赖项也更新到了最新版本
依赖项 | 从 | 到 | |
---|---|---|---|
Akka HTTP | 10.1.15 | 10.2.10 | |
Guice | 4.2.3 | 6.0.0 | 使用 guice 时 |
HikariCP | 3.4.5 | 5.0.1 | 使用 jdbc 时 |
scala-xml | 1.3.1 | 2.2.0 | |
Jackson 和 Jackson 模块 Scala | 2.11.4 | 2.14.3 | |
SBT 原生打包器 | 1.5.2 | 1.9.16 | |
Logback | 1.2.12 | 1.4.11 | |
SLF4J API | 1.7.36 | 2.0.7 | |
Caffeine | 2.8.8 | 3.1.7 | 使用 caffeine 时 |
sbt-web | 1.4.4 | 1.5.0 | |
sbt-js-engine | 1.2.3 | 1.3.0 | |
Guava | 30.1.1 | 32.1.2 | |
Lightbend SSL 配置 | 0.4.3 | 0.6.1 | |
Java JSON Web 令牌 (JJWT) | 0.9.1 | 0.11.5 | |
TypeTools | 0.5.0 | 0.6.3 | 由 Java 路由 DSL 使用 |
FluentLenium | 3.7.1 | 6.0.0 | 现在是 io.fluentlenium |
Selenium | 3.141.59 | 4.11.0 | |
Selenium HtmlUnitDriver | 2.36.0 | 4.11.0 | 与 Selenium 版本相同 |
specs2 | 4.8.3 | 4.20.2 | |
JUnit 接口 | 0.11 | 0.13.3 | |
Joda-Time | 2.10.14 | 2.12.5 | 使用 jodaForms 时 |
Hibernate 验证器 | 6.1.7 | 6.2.5.Final | 使用 PlayJava 插件时 |
§更改的 groupId
我们现在在 com.typesafe.play
命名空间下发布所有 Play 工件和库。因此,我们必须对以下库进行调整
工件 | 旧的 groupId | 新的 groupId |
---|---|---|
play-file-watch |
com.lightbend.play |
com.typesafe.play |
sbt-twirl |
com.typesafe.sbt |
com.typesafe.play |
§更改的工件名称
为了确保所有工件的命名一致,其中每个名称都以 play-
为前缀,我们对剩余的 artifactId 进行了调整
旧的 artifactId | 新的 artifactId |
---|---|
build-link |
play-build-link |
filters-helpers |
play-filters-helpers |
routes-compiler |
play-routes-compiler |
run-support |
play-run-support |
§已删除的库
以下依赖项已从 Play 中删除
-
"org.scala-lang.modules" %% "scala-java8-compat"
由于 Play 2.9 中已删除 Scala 2.12 支持,因此不再需要引入此依赖项。使用scala.jdk
下的类,这些类已添加到 Scala 2.13 中的标准库中。 -
"jakarta.xml.bind" % "jakarta.xml.bind-api"
升级后的 JJWT 依赖项不再使用 JAXB。 -
"org.mortbay.jetty.alpn" % "jetty-alpn-agent"
和
"com.lightbend.sbt" % "sbt-javaagent"
由于 Java 11 是 Play 2.9 的最低要求的 Java 版本,并且开箱即用地支持 ALPN,因此这些依赖项不再需要。 -
"jakarta.transaction" % "jakarta.transaction-api"
它毫无用处,似乎一直被忽略到目前为止。
下一步:Scala 3 迁移指南
发现文档中的错误?此页面的源代码可以在 这里 找到。阅读完 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?前往 我们的社区论坛 与社区进行交流。