§Play 2.5 移行ガイド
これは、Play 2.4からPlay 2.5への移行ガイドです。以前のバージョンのPlayから移行する必要がある場合は、最初にPlay 2.4 移行ガイドに従う必要があります。
このページに記載されている情報に加えて、いくつかのトピックに関するより詳細な移行情報があります。
- ストリーム移行ガイド – Play APIの多くでイテレータの代わりに使われるようになったAkkaストリームへの移行。
- Java移行ガイド - Javaアプリケーションの移行。Playは、機能型にネイティブのJava型を使用するようになり、Javaでいくつかの新しいカスタマイズ可能なコンポーネントを提供します。
Lucidchartは、Play 2.3.xからPlay 2.5.xへのアップグレードに関する有益なブログ記事もまとめています。
§移行方法
sbtでPlayプロジェクトをロード/実行する前に、次の手順に従ってsbtビルドを更新する必要があります。
§Playのアップグレード
project/plugins.sbtのPlayバージョン番号を更新して、Playをアップグレードします。
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.x")
ここで、2.5.xの「x」は、使用するPlayのマイナーバージョンです。たとえば、2.5.0です。
§sbtを0.13.11にアップグレード
Play 2.5はsbt 0.13.8でも動作しますが、最新のsbtバージョンである0.13.11にアップグレードすることをお勧めします。 sbtの0.13.11リリースには、多くの改善とバグ修正が含まれています。
project/build.propertiesを次のように更新します。
sbt.version=0.13.11
§Play Slickのアップグレード
プロジェクトでPlay Slickを使用している場合は、アップグレードする必要があります。
libraryDependencies += "com.typesafe.play" %% "play-slick" % "2.0.0"
または
libraryDependencies ++= Seq(
"com.typesafe.play" %% "play-slick" % "2.0.0",
"com.typesafe.play" %% "play-slick-evolutions" % "2.0.0"
)
§Play Ebeanのアップグレード
プロジェクトでPlay Ebeanを使用している場合は、アップグレードする必要があります。
addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "3.0.0")
§ScalaTest + Playのアップグレード
プロジェクトでScalaTest + Playを使用している場合は、アップグレードする必要があります。
libraryDependencies ++= Seq(
"org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % "test"
)
§Scala 2.10のサポートは終了しました
Play 2.3と2.4は、Scala 2.10と2.11の両方をサポートしていました。Play 2.5ではScala 2.10のサポートが終了し、現在はScala 2.11のみをサポートしています。これにはいくつかの理由があります。
-
Play 2.5の内部コードは、scala-java8-compatライブラリを広範囲に使用していますが、これはScala 2.11のみをサポートしています。scala-java8-compatには、Scalaの
FutureやJavaのCompletionStageなど、多くのScala型とJava 8型の間の変換があります。(このライブラリもコードに役立つかもしれません。) -
Playの次のバージョンでは、Scala 2.12のサポートが追加される可能性があります。今後の2.12への移行が容易になるように、PlayがScala 2.11に移行する時期です。
§移行方法
ScalaとJavaの両方のユーザーは、sbtがScala 2.11を使用するように設定する必要があります。 プロジェクトにScalaコードがない場合でも、Play自体がScalaを使用するため、適切なScalaライブラリを使用するように設定する必要があります。
sbtでScalaバージョンを設定するには、scalaVersionキーを設定するだけです。例:
scalaVersion := "2.11.8"
単一のプロジェクトビルドがある場合、この設定はbuild.sbtの独自の行に配置できます。ただし、マルチプロジェクトビルドがある場合、Scalaバージョンの設定は各プロジェクトで設定する必要があります。通常、マルチプロジェクトビルドでは、すべてのプロジェクトで共有されるいくつかの共通設定があります。これは設定を配置するのに最適な場所です。例:
def common = Seq(
scalaVersion := "2.11.8"
)
lazy val projectA = (project in file("projectA"))
.enablePlugins(PlayJava)
.settings(common: _*)
lazy val projectB = (project in file("projectB"))
.enablePlugins(PlayJava)
.settings(common: _*)
§Logback構成の変更
Logbackに対するPlayのハードコードされた依存関係を削除する変更の一環として(ハイライトを参照)、Logback構成で使用されるクラスの1つを別のパッケージに移動する必要がありました。
§移行方法
Logback構成ファイル(logback*.xml)を更新し、古いplay.api.Logger$ColoredLevelへの参照を新しいplay.api.libs.logback.ColoredLevelクラスに変更する必要があります。
変更後の新しい構成は次のようになります。
<conversionRule conversionWord="coloredLevel"
converterClass="play.api.libs.logback.ColoredLevel" />
コンパイル時依存性注入を使用する場合は、アプリケーションローダーをLogger.configure(...)の使用から次のように変更する必要があります。
LoggerConfigurator(context.environment.classLoader).foreach { _.configure(context.environment) }
さまざまなロギングフレームワークでPlayを設定する方法の詳細については、ドキュメントのロギングの構成セクションを参照してください。
§Play WSをAsyncHttpClient 2にアップグレード
Play WSは、AsyncHttpClient 2を使用するようにアップグレードされました。これは、Netty 4.0を使用する大規模なアップグレードです。 AHC 2.0の変更のほとんどは水面下で行われていますが、AHCにはWS APIに対する破壊的な変更を必要とするいくつかの重要なリファクタリングがあります。
AsyncHttpClientConfigは、DefaultAsyncHttpClientConfigに置き換えられました。allowPoolingConnectionとallowSslConnectionPoolは、AsyncHttpClientでは単一のkeepAlive変数に結合されています。したがって、play.ws.ning.allowPoolingConnectionとplay.ws.ning.allowSslConnectionPoolは無効であり、構成されている場合は例外をスローします。webSocketIdleTimeoutは削除されたため、AhcWSClientConfigでは使用できなくなりました。ioThreadMultiplierは削除されたため、AhcWSClientConfigでは使用できなくなりました。FluentCaseInsensitiveStringsMapクラスは削除され、NettyのHttpHeaderクラスに置き換えられました。Realm.AuthScheme.Noneは削除されたため、WSAuthSchemeでは使用できなくなりました。
さらに、いくつかの小さな変更があります。
- 適切なAsyncHttpClientライブラリ名を反映するために、パッケージ
play.api.libs.ws.ningはplay.api.libs.ws.ahcに名前が変更され、Ning*クラスはAhc*に名前が変更されました。さらに、AHC構成設定はplay.ws.ahcプレフィックスに変更されました。つまり、play.ws.ning.maxConnectionsPerHostはplay.ws.ahc.maxConnectionsPerHostになりました。 - 非推奨のインターフェース
play.libs.ws.WSRequestHolderが削除されました。 play.libs.ws.play.WSRequestインターフェースは、F.Promiseの代わりにjava.util.concurrent.CompletionStageを返すようになりました。Play.currentまたはPlay.applicationに依存する静的メソッドは非推奨になりました。- Play WSはコンテンツタイプから文字セットを推測し、設定されていない場合はリクエストの
Content-Typeヘッダーに文字セットを追加します。これにより、混乱とバグが発生したため、2.5.xでは、Content-Typeヘッダーに推測された文字セットが自動的に含まれることはありません。Content-Typeヘッダーを明示的に設定すると、設定はそのまま有効になります。
§非推奨のGlobalSettings
Playのグローバル状態から離れるための継続的な取り組みの一環として、GlobalSettingsとアプリケーションのGlobalオブジェクトは非推奨になりました。詳細については、Play 2.4移行ガイドで、GlobalSettingsの使用を止める方法を参照してください。
§削除されたプラグインAPI
Play 2.4 で非推奨となった Plugins API は、Play 2.5 で削除されました。Plugins API は、再利用可能なコンポーネントをよりクリーンで柔軟な方法で構築できる Play の依存性注入とモジュールシステムに置き換えられました。プラグインから依存性注入への移行方法の詳細については、Play 2.4 マイグレーションガイドを参照してください。
§InjectedRoutesGenerator で生成されるルート
ルートは、コントローラがシングルトンオブジェクトであると仮定していた以前の StaticRoutesGenerator ではなく、依存性注入に対応した InjectedRoutesGenerator を使用して生成されるようになりました。
以前の動作に戻す場合(例えば、コードに "object MyController" がある場合)、build.sbt ファイルに次の行を追加してください。
routesGenerator := StaticRoutesGenerator
build.sbt の代わりに Build.scala を使用している場合は、routesGenerator 設定キーをインポートする必要があります。
import play.sbt.routes.RoutesCompiler.autoImport._
静的ルートジェネレータによる静的コントローラの利用は非推奨ではありませんが、依存性注入を利用したクラスの使用に移行することを推奨します。
§静的コントローラを依存性注入に置き換え
controllers.ExternalAssets はクラスになり、静的な同等のものはありません。controllers.Assets と controllers.Default もクラスであり、静的な同等のものは存在しますが、クラス版を使用することを推奨します。
§移行方法
推奨される解決策は、すべてのコントローラにクラスを使用することです。InjectedRoutesGenerator がデフォルトになったため、ルートファイル内のコントローラはオブジェクトではなくクラスであると想定されます。
静的コントローラをまだ使用している場合は、StaticRoutesGenerator(上記参照)を使用し、routes ファイル内のルートの先頭に @ 記号を追加できます(例:)。
GET /assets/*file @controllers.ExternalAssets.at(path = "/public", file)
§非推奨の play.Play および play.api.Play メソッド
play.Play では、以下のメソッドが非推奨となりました。
public static Application application()public static Mode mode()public static boolean isDev()public static boolean isProd()public static boolean isTest()
同様に、暗黙的な Application を受け取り、def classloader(implicit app: Application) のように Application に委譲する play.api.Play のメソッドも非推奨になりました。
§移行方法
これらのメソッドは、play.Application または play.Environment のいずれかに委譲します。それらを使用するコードは、関連するクラスを注入するために依存性注入を使用する必要があります。
組み込みの Play コンポーネントを移行するには、Play 2.4 マイグレーションガイドの依存性注入されたコンポーネントのリストを参照する必要があります。
たとえば、次のコードでは、Scala のコントローラに環境と設定を注入します。
class HomeController @Inject() (environment: play.api.Environment,
configuration: play.api.Configuration)
extends Controller {
def index = Action {
Ok(views.html.index("Your new application is ready."))
}
def config = Action {
Ok(configuration.underlying.getString("some.config"))
}
def count = Action {
val num = environment.resource("application.conf").toSeq.size
Ok(num.toString)
}
}
§レガシーコンポーネントの処理
通常、使用するコンポーネントはアプリケーション全体に依存する必要はありませんが、アプリケーションを必要とするレガシーコンポーネントを処理しなければならない場合があります。これは、アプリケーションをコンポーネントの 1 つに注入することで処理できます。
class FooController @Inject() (appProvider: Provider[Application])
extends Controller {
implicit lazy val app = appProvider.get()
def bar = Action {
Ok(Foo.bar(app))
}
}
この場合、循環依存関係を避けるために、通常は Provider[Application] を使用することに注意してください。
さらに良いのは、静的メソッドをインスタンスメソッドに変換する独自の *Api クラスを作成することです。
class FooApi @Inject() (appProvider: Provider[Application]) {
implicit lazy val app = appProvider.get()
def bar = Foo.bar(app)
def baz = Foo.baz(app)
}
これにより、DI で得られるテスト容易性の恩恵を受けながら、グローバルな状態を使用するライブラリを引き続き使用できます。
§Content-Type charset の変更
Play 2.5 より前は、Play は、特に application/json と application/x-www-form-urlencoded のように、charset パラメータを定義しない特定のコンテンツタイプに charset パラメータを追加していました。現在、Content-Type はデフォルトで charset なしで送信されます。これは、WS でリクエストを送信する場合と、Play アクションからレスポンスを返す場合の両方に当てはまります。charset パラメータを送信する必要がある非準拠のクライアントまたはサーバーがある場合は、Content-Type ヘッダーを明示的に設定できます。
§Guice インジェクタと Guice ビルダーの変更
デフォルトでは、Guice は循環内のインターフェースをプロキシすることで循環依存関係を解決できます。循環依存関係は一般的にコードの臭いであり、プロバイダを注入して循環を断ち切ることもできるため、デフォルトの Guice インジェクタでこの機能を無効にすることを選択しました。他の DI フレームワークもこの機能を持っている可能性は低いため、Play モジュールを作成する際に問題が発生する可能性があります。
現在、Guice ビルダー (GuiceInjectorBuilder および GuiceApplicationBuilder) に、Guice がクラスを注入する方法をカスタマイズするための 4 つの新しいメソッドがあります。
* disableCircularProxies: 循環依存関係を解決するためにインターフェースをプロキシする上記のような動作を無効にします。プロキシを許可するには、disableCircularProxies(false) を使用します。
* requireExplicitBindings: モジュールで明示的にバインドされているクラスのみをインジェクタに注入するように指示します。バインディングを検証するテストで役立ちます。
* requireAtInjectOnConstructors: クラスをインスタンス化するには、@Inject でアノテーションが付けられたコンストラクタを必要とします。
* requireExactBindingAnnotations: @Named("foo") Foo を注入するときに、Guice のエラーが発生しやすい機能である @Named Foo のバインディングを置き換えることを無効にします。
§CSRF の変更
Play の CSRF フィルタをブラウザプラグインの脆弱性や新しい拡張機能に対してより耐性を持たせるために、CSRF フィルタのデフォルト構成は大幅に保守的になりました。変更点は次のとおりです。
POSTリクエストをブラックリスト化する代わりに、GET、HEAD、OPTIONSリクエストのみがホワイトリスト化され、他のすべてのリクエストには CSRF チェックが必要です。つまり、DELETEおよびPUTリクエストがチェックされるようになりました。application/x-www-form-urlencoded、multipart/form-data、およびtext/plainリクエストをブラックリスト化する代わりに、コンテンツタイプがないものを含むすべてのコンテンツタイプのリクエストに CSRF チェックが必要です。この結果の 1 つとして、application/jsonを使用する AJAX リクエストは、Csrf-Tokenヘッダーに有効な CSRF トークンを含める必要があります。X-Requested-Withなどのステートレスヘッダーベースのバイパスは、デフォルトで無効になっています。
特定のヘッダーを持つリクエストに対して新しい CSRF 保護をバイパスするための新しい構成オプションがあります。この構成オプションは、デフォルトで Cookie および Authorization ヘッダーに対してオンになっているため、通常はセッション認証を使用しない REST クライアントは、CSRF トークンを送信しなくても引き続き機能します。
ただし、構成オプションでは、これらのヘッダーのないすべてのリクエストが許可されるため、他の認証スキーム (NTLM、TLS クライアント証明書) を使用するアプリケーションは CSRF に対して脆弱になります。これらのアプリケーションは、認証済みの (Cookie なしの) リクエストが CSRF フィルタによって保護されるように、構成オプションを無効にする必要があります。
最後に、CORS フィルタによって信頼されているオリジンに対して CSRF チェックを無効にするための追加オプションが追加されました。CORS フィルタが、フィルタチェーンで CSRF フィルタの前に来る必要があることに注意してください。
Play の以前のデフォルトの動作は、次の構成を application.conf に追加することで復元できます。
play.filters.csrf {
header {
bypassHeaders {
X-Requested-With = "*"
Csrf-Token = "nocheck"
}
protectHeaders = null
}
bypassCorsTrustedOrigins = false
method {
whiteList = []
blackList = ["POST"]
}
contentType.blackList = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]
}
§CSRF トークンの取得
以前は、CSRF トークンは任意のアクションで HTTP リクエストから取得できました。現在、CSRF.getToken が機能するには、CSRF フィルタまたは CSRF アクションのいずれかが必要です。フィルタを使用していない場合は、Scala の CSRFAddToken アクションまたは Java アノテーションの AddCSRFToken を使用して、トークンがセッションに含まれていることを確認できます。
また、署名が無効な場合、CSRF トークンが空になる (テンプレートヘルパーで例外をスローする) というマイナーなバグがこのリリースで修正されました。これで、同じリクエストで再生成され、テンプレートヘルパーと CSRF.getToken からトークンが引き続き利用できるようになります。
詳細については、Java および Scala の CSRF ドキュメントをお読みください。
§非推奨の Crypto
Play 1.x から、Play にはいくつかの暗号化操作を提供する Crypto オブジェクトが付属しています。これは Play によって内部的に使用されます。Crypto オブジェクトはドキュメントには記載されていませんが、scaladoc では「暗号化ユーティリティ」として記載されています。
さまざまな理由から、便宜上暗号化ユーティリティを提供することは実行可能ではないことが判明しました。2.5.x では、Play 固有の機能が CookieSigner、CSRFTokenSigner、AESSigner トレイトに分割され、Crypto シングルトンオブジェクトが非推奨となりました。
§移行方法
暗号化の移行は、特に暗号化プリミティブの安全でない構築がある場合に、ユースケースによって異なります。簡単な説明は、可能であれば Kalium を使用し、そうでない場合は Tink またはストレート JCA を使用することです。
詳細については、Crypto の移行を参照してください。
§Netty 4 のアップグレード
Netty が 3.10 から 4.0 にアップグレードされました。この結果の 1 つとして、Netty チャネルオプションを設定するための構成オプションが変更されました。すべてのオプションのリストはこちらで確認できます。
§移行方法
play.server.netty.option キーを、ChannelOption で定義されている新しいキーを使用するように変更してください。より一般的に使用されているもののいくつかのマッピングは次のとおりです。
| 古い | 新しい |
|---|---|
play.server.netty.option.backlog |
play.server.netty.option.SO_BACKLOG |
play.server.netty.option.child.keepAlive |
play.server.netty.option.child.SO_KEEPALIVE |
play.server.netty.option.child.tcpNoDelay |
play.server.netty.option.child.TCP_NODELAY |
§sendFile、sendPath、sendResource メソッドの変更
Java (play.mvc.StatusHeader) および Scala (play.api.mvc.Results.Status) API には、以前は次の動作がありました。
| API | メソッド | デフォルト |
|---|---|---|
| Scala | play.api.mvc.Results.Status.sendResource |
インライン |
| Scala | play.api.mvc.Results.Status.sendPath |
添付ファイル |
| Scala | play.api.mvc.Results.Status.sendFile |
添付ファイル |
| Java | play.mvc.StatusHeader.sendInputStream |
なし |
| Java | play.mvc.StatusHeader.sendResource |
インライン |
| Java | play.mvc.StatusHeader.sendPath |
添付ファイル |
| Java | play.mvc.StatusHeader.sendFile |
インライン |
言い換えれば、ファイルを配信するときに、inline モードと attachment モードが混在していました。現在、ファイル、パス、およびリソースを配信する場合、デフォルトの動作として inline を使用します。もちろん、これらのメソッドに存在するパラメータを使用することで、これらの 2 つのモードを切り替えることができます。
このドキュメントにエラーを見つけましたか?このページのソースコードはこちらにあります。ドキュメントガイドラインを読んだ後、プルリクエストを自由に送信してください。質問や共有したいアドバイスがありますか?コミュニティフォーラムでコミュニティとの会話を始めましょう。