ドキュメント

§はじめに

このリリースのハイライトについて詳しく説明する前に、Play Framework をビジネスで使用する場合に関連する可能性が高い以下のトピックをよく理解しておくことを強くお勧めします。

また、現在、追加のプレミアムスポンサーを探していることをお知らせいたします。貴社がそのような役割に財政的に対応できる場合は、ご連絡いただければ幸いです。詳細はこちらをご覧ください。

最後に、プレミアムスポンサーとすべての個人(現在および過去のスポンサー)への心からの感謝の意を表したいと思います。皆様の寛大なご寄付のおかげで、Play Framework の開発を続けることができています。
皆様のサポートなしでは、このリリースは実現しませんでした!

§Play 2.9 の新機能

このセクションでは、Play 2.9 の新機能について説明します。Play 2.9 への移行時に必要な変更について学習するには、Play 2.9 移行ガイドを参照してください。

このページは、同時にリリースされた Play 2.9 と同じ新機能とバグ修正を含むPlay 3.0にも適用されます。唯一の違いは、Play 2.9 は Akka と Akka HTTP をベースに構築されているのに対し、Play 3.0 は Pekko と Pekko HTTP をベースに構築されていることです。Play 2.9 への移行後に Pekko を使用して Play 3.0 への移行を続ける場合は、Play 3.0 移行ガイドを参照してください。

§Scala 3 のサポート

Play 2.9 は Scala 3 アーティファクトを提供します!これで、Scala 3.3.1 以降を Play と一緒に使用できるようになりました。3.0 から 3.2 までの Scala バージョンはサポートされていないことに注意してください。いくつかの移行手順が必要になることに注意してください。包括的なガイダンスについては、Scala 3 移行ガイドを参照してください。

Play はScala LTS(長期サポート)バージョンのみをサポートしていることを強調することが重要です。その結果、Scala 3.3 LTS と次の LTS バージョンの間の Scala リリースは、Play によって公式にサポートされません。ただし、そのような Scala バージョンで Play を使用することは依然として可能です。

Scala 2.13 はまだメンテナンスされており、今後何年にもわたって新しいScala 2.13 リリースが予定されているため、Play アプリケーションを Scala 3 に移行する必要性は当面ありません。それにもかかわらず、将来のロードマップでアプリケーションのアップグレードを検討することをお勧めします。

コードベースによっては、既存の Play アプリケーションを Scala 3 に移行することはかなりの作業になる可能性があります。最初はScala 2.13 のまま移行して、Play 2.9 を使用することを強くお勧めします。この方法では、すべてが意図したとおりに機能することを確認できます。その後、移行してScala 3を使用できます。

§Java 17 と 21 のサポート

Play 2.9 は、Java 21 LTS と Java 17 LTS をすぐにサポートする最初のメジャーバージョンです。Play 2.8.15 で Java 17 を使用することは既に可能でしたが、これにはいくつかの調整が必要でした

Play 2.9 にアップグレードする際には、少なくとも Java 17 LTS へのアップグレードを検討することを強くお勧めします。今後の Play 2.x リリース(バージョン 2.10)では、Java 11 のサポートを終了する可能性があります。この推奨事項を行う決定は、Play が依存するライブラリが既に Java 11 アーティファクトの提供を停止しているという事実によって裏付けられています。そのため、これらの依存関係をアップグレードできなくなる可能性があるため、将来セキュリティ上の問題が発生しないようにしたいと考えています。さらに、Play 2.9 リリース前に実施したローカルベンチマークに興味があるかもしれません。TechEmpower の Framework Benchmarks スイートを使用しました。結果は、Java 17 にアップグレードするだけでパフォーマンスが向上し、アプリケーションのパフォーマンスが向上する可能性があることを示しています。

Java 17 と Java 21 で自己署名証明書を使用して HTTPS ポートをバインドすると、問題が発生する可能性があることに注意してください。この問題の詳細については、Play 2.9 移行ガイドの"自己署名証明書の生成が Java 17 と Java 21 で失敗する"を参照してください。

Play、スタンドアロンモジュール、サンプル、およびシードプロジェクトはすべて、OpenJDK Temurin バージョン 11、17、および 21 に対して厳格にテストされています。

Play は Java LTS バージョンのみをサポートします。したがって、Java 21 LTS と次の LTS の間の Java リリースは、そのようなバージョンで Play を使用できる場合でも、Play から公式にサポートされません。

§Scala 2.12、sbt 0.13、および Java 8 のサポート終了

Scala 2.12 とともに、このリリースでは Java 8 のサポートを終了することを選択しました。この決定は、Play が依存するライブラリの数がますます増加し、Java 8 アーティファクトの提供を停止していることが原因です。さらに、Play 2.9 はついに sbt 0.13 のサポートを終了しました。Play はさまざまな sbt 1.x バージョンと互換性を維持する可能性が高いですが、公式サポートは sbt バージョン 1.9.6 以降に拡張されています。したがって、最新の sbt バージョンを使用してセットアップを維持することを強くお勧めします。

§Akka HTTP 10.2

Play 2.9 は Akka 2.6 を引き続き使用していますが、10.1 からアップグレードされた Akka HTTP 10.2 に進化しました。Play 2.9 はこれ以上のバージョンには対応しないことに注意することが重要です。この決定は、Akka 2.6 と Akka HTTP 10.2 が Apache License によって管理されている最後のバージョンを表しているという事実を根拠としています。その後のAkka リリースは BSL の対象となりますが、Play は意図的に使用していません。レビューすることを強くお勧めします。

§Guice のバージョン 6 へのアップグレード

Play で使用されるデフォルトの依存関係注入フレームワークである Guice がバージョン 6.0.0(4.2.3 から)にアップグレードされました。5.0.15.1.0、および6.0.0のリリースノートを参照してください。Guice 6 のリリースノートに記載されているように、javax.inject 名前空間を引き続き使用できます。あるいは、必要に応じて jakarta.inject に切り替えることもできます。

次のメジャーリリースの Play では、javax.inject をサポートしなくなったGuice 7にアップグレードすることに注意することが重要です。

§Jackson のバージョン 2.14 へのアップグレード

Jackson は、バージョン 2.11 を超える待望のアップデートを受けました。Play 2.9 では、新しいバージョンが既に利用可能である場合でも、デフォルトの Jackson バージョンは 2.14 です。この決定は、主に Akka と広範な互換性の状況によって影響されています。Akka と Pekko のどちらもこれらの新しい Jackson バージョンにまだアップグレードしておらず、これらの重要なコンポーネントとの互換性の問題を回避することを目指しています。ただし、必要であれば、こちらで説明されているのと同じ方法で、新しいバージョンにアップグレードできます。

§Jakarta Persistence への移行

Java Persistence API からJakarta Persistence APIへの移行により、Hibernate 6 以降と EclipseLink 3 以降がサポートされるようになりました。Hibernate または EclipseLink を新しい名前空間にアップグレードする方法の詳細については、対応する移行ガイドを参照してください。

§sbt-web と sbt-js-engine のアップグレード

sbt-websbt-js-engine は大幅なリファクタリングが行われ、いくつかの注目すべき改善が行われました。

sbt-web はAkkaへの依存関係を削除し、両方のコードベースを簡素化し、副次的な効果としてメモリリークに対処しました。以前はスタンドアロンプロジェクトだったnpmjs-engineはsbt-js-engineに統合されました。

Play が付属するバージョン 1.3.0 以降、sbt-js-engine は、Node.js をサポートするローカルにインストールされた js エンジンを使用する場合に、システムの npm コマンドを検出しようとします。新しい npm コマンドをサポートしていない古い npm webjars の代わりに、システムの npm を使用します。この動作は現在デフォルトであり、npmPreferSystemInstalledNpm := false で無効にすることができます。この設定により、使用中のエンジンに関係なく、webjar npm が使用されます。

さらに、バージョン1.3.0以降、npmSubcommand := NpmSubcommand.Install を設定することで、使用するnpmサブコマンドを指定できるようになります(使用可能なオプションにはInstallCiUpdateがあり、後者はデフォルトです)。

§HikariCPのアップグレード

PlayのデフォルトのJDBC接続プールであるHikariCPがバージョン5にアップグレードされました。このバージョンの詳細については、変更ログを参照してください。このアップグレードにより、新しい設定オプションplay.db.prototype.hikaricp.keepaliveTime(または特定のデータベース、例えばdefaultに対してはdb.default.hikaricp.keepaliveTime)が導入されました。この設定は、1 minuteのような期間値を受け入れます。

この設定に関するより詳細な情報については、HikariCPのGitHub READMEを参照してください。

§その他の追加機能

§Result属性

リクエスト属性と同様に、Playは現在、レスポンス属性をサポートしています。これらの属性は同じように機能し、将来のアクセスのために余分な情報をレスポンスオブジェクト内に保存できます。この機能は、アクション合成やフィルターを利用する場合に特に役立ちます。メソッドはリクエスト属性で使用されるものと同じであるため、リクエスト属性の動作方法を参照し、同様のアプローチをレスポンスオブジェクトに適用できます。

§遅延ボディパース

デフォルトでは、ボディパースはアクション合成で定義されたアクションが処理されるに実行されます。この順序は変更できるようになりました。理由と変更方法の詳細については、JavaScalaのドキュメントを参照してください。

§アクション合成へのWebSocketアクションメソッドの包含

Play Javaを使用する場合は、アクション合成を利用した次のコントローラーの例を考えてください。

@Security.Authenticated
public class HomeController extends Controller {

    @Restrict({ @Group({"admin"}) })
    public WebSocket socket() {
        return WebSocket.Text.acceptOrResult(request -> /* ... */);
    }
}

以前は、上記のようにsocket()メソッドで示されているWebSocketを処理する場合、アクション合成は適用されませんでした。その結果、@Security.Authenticated@RestrictDeadbolt 2ライブラリのもの)などのアノテーションは効果がなく、実行されませんでした。Java WebSocketのドキュメントでは、ユーザー権限などを確認するためにacceptOrResultメソッドを使用することを推奨しています。

Play 2.9以降、新しく導入された設定オプションplay.http.actionComposition.includeWebSocketActionstrueに設定することで、有効にできます。アクション合成へのWebSocketアクションメソッドの包含により、@Security.Authenticated@Restrictでアノテーションされたアクションが期待通りに実行されるようになります。このアプローチの利点は、アノテーションアクションメソッドに既に実装されている認証または承認コードをacceptOrResultメソッドで複製する必要がない可能性があることです。

§設定可能なEvolutionsスクリプトの場所

新しいplay.evolutions[.db.default].path設定を使用して、進化スクリプトの場所をカスタマイズできるようになりました。これにより、Playプロジェクト内の特定の場所に進化スクリプトを保存したり、絶対パスまたは相対パスを使用してプロジェクトのルートフォルダーの外に保存したりできます。詳細については、Evolutionsのドキュメントを参照してください。

§Evolutionsスクリプトでの変数置換

Evolutionsスクリプトは、application.confで定義されている対応する値で置き換えられるプレースホルダーをサポートするようになりました。

play.evolutions.db.default.substitutions.mappings = {
  table = "users"
  name = "John"
}

例えば、次のような進化スクリプトは

INSERT INTO $evolutions{{{table}}}(username) VALUES ('$evolutions{{{name}}}');

進化適用プロセス中に次のように変換されます。

INSERT INTO users(username) VALUES ('John');

注:Evolutionsメタテーブルには、プレースホルダーが置き換えられる前の生のSQLスクリプトが保持されます。

メタテーブルはデフォルトでplay_evolutionsという名前です。これはplay.evolutions.db.default.metaTableを設定することで変更できます。

変数置換は大文字と小文字を区別しません。したがって、$evolutions{{{NAME}}}$evolutions{{{name}}}と同じです。

プレースホルダー構文のプレフィックスとサフィックスも変更できます。

# Change syntax to @{...}
play.evolutions.db.default.substitutions.prefix = "@{"
play.evolutions.db.default.substitutions.suffix = "}"

Evolutionsモジュールは、変数を置換しない場合の脱出メカニズムをサポートしています。このメカニズムはデフォルトで有効になっています。無効にするには、次のように設定します。

play.evolutions.db.default.substitutions.escapeEnabled = false

有効になっている場合、!$evolutions{{{...}}}を使用して変数置換をエスケープできます。例えば

INSERT INTO notes(comment) VALUES ('!$evolutions{{{comment}}}');

は置換で置き換えられず、最終的なSQLでは次のように なります。

INSERT INTO notes(comment) VALUES ('$evolutions{{{comment}}}');

このエスケープメカニズムは、substitutions.mappings設定に変数マッピングが定義されているかどうかに関係なく、すべての!$evolutions{{{...}}}プレースホルダーに適用されます。

§Evolutionsメタデータテーブルのカスタムネーミング

各データソースのplay_evolutionsメタデータテーブルの名前を変更できるようになりました。例えば、defaultデータソースのメタテーブルをmigrationsという名前にしたい場合は、次の設定を行います。

play.evolutions.db.default.metaTable = "migrations"

useLocks設定でロックテーブルを使用している場合、ロックテーブルにも進化メタデータテーブルと同じ名前が_lock接尾辞付きで付けられます(migrations_lockではなくplay_evolutions_lock)。詳細については、Evolutionsのドキュメントを参照してください。

既存のPlayアプリケーションでこの機能を使用する場合は、この設定を行う前にメタテーブルを手動で名前変更してください。

§空のボディまたは空のファイル名でのファイルアップロードの許可

次のように設定できます。

play.http.parser.allowEmptyFile = true

ファイル名またはファイル自体が空であるかに関係なく、空のmultipart/form-dataファイルアップロードを許可します。デフォルトでは、この設定はfalseに設定されています。

§追加のエラー情報を含むリクエスト属性

エラーハンドラー内では、利用可能な場合、「httpエラー情報」リクエスト属性にアクセスできます。この属性には、エラー処理に役立つ追加情報が含まれています。現在、エラーハンドラーが最初に呼び出された場所に関する詳細を取得できます。

Java
request.attrs.getOptional(play.http.HttpErrorHandler.Attrs.HTTP_ERROR_INFO).map(info => info.origin()).orElse("<unknown error origin>")
Scala
request.attrs.get(play.api.http.HttpErrorHandler.Attrs.HttpErrorInfo).map(_.origin).getOrElse("<unknown error origin>")

現在、Play 2.9はエラーハンドラーの起点に応じて次の値を提供します。

サードパーティモジュールは独自の起点を紹介する可能性があります。また、将来のPlayリリースには、さらにエラー関連の情報が含まれる可能性があります。

§CORSフィルターは*ワイルドカードをサポート

CORSフィルターのallowedOrigins設定は、特別な意味を持つワイルドカード*を受け入れるようになりました。リクエストのオリジンがリスト内の他のオリジンと一致しない場合、Access-Control-Allow-Origin: *が送信されます。

play.filters.cors.allowedOrigins = ["*"]

詳細については、CORSフィルターのドキュメントを参照してください。

§新しいIPフィルター

IPアドレスのブラックリストまたはホワイトリストによってアクセスを制限するための新しいフィルターが導入されました。IPフィルターのページで詳細情報を確認してください。

§スタンドアロンライブラリとしてのPlay設定プロジェクト

Typesafe ConfigをラップするPlayのplay.api.Configurationクラスは、スタンドアロンライブラリとして使用できるようになりました。フットプリントを最小限に抑えることを目指しました。Typesafe Config以外では、ロギングにslf4j-apiと、Play自体とPlay SBTプラグインに必要な2つの例外クラスを含むPlayのplay-exceptionsプロジェクトのみに依存しています。

ライブラリを使用するには、build.sbtに含めることで、任意のScalaプロジェクトに追加します。

libraryDependencies += "com.typesafe.play" %% "play-configuration" % "<PLAY_VERSION>"

§UUID PathBindableExtractorの追加

ルーティングDSLは、すぐにUUIDをバインドする機能を含んでいます。

§新しいサーバーバックエンド設定キー

これらの新しい設定の機能の詳細については、Akka HTTPNettyのサーバーバックエンド設定ページ、および「サーバーを正常にシャットダウンする」方法に関するドキュメントを参照してください。

§強化されたビルドインフラストラクチャ

余談ですが、GitHub Play Framework組織の下にあるすべてのリポジトリをTravis CIからGitHub Actionsに移行したことをお知らせします。私たちの経験では、GitHub Actionsは、GitHubとのシームレスな統合により、より信頼性が高く、大幅に高速で、保守が容易であることが証明されています。この移行を促進するために尽力してくれたSergey Morgunovさんに感謝いたします。彼は、優れた再利用可能なGitHubワークフローを作成することに多大な時間を費やしました。

sbt-ci-releaseのおかげで、新しいバージョンのリリースプロセスが合理化されました。これで、GitHubにGitタグをプッシュするだけで、新しいバージョンを生成できます。これにより、過去によく発生していた、開発者のマシンでローカルにアーティファクトを公開する際の潜在的なエラーを心配する必要がなくなります。

Scala開発者コミュニティで現在非常に一般的になっているヘルパーに切り替えることで、更新されたライブラリを含む新しいバージョンのシームレスで迅速なリリースをさらに達成できます。これらのツールは広く認識されていますが、この機会にその重要性を認めたいと思います。 Scala StewardRelease Drafterなどのツールの作成者とメンテナーに心から感謝申し上げます。彼らの努力は、Playの継続的な提供に不可欠な役割を果たしています。

§Play 2.10 / Play 3.1の計画

Play 2.10 / Play 3.1に含める予定の内容の概要を事前に提供し、これらの変更を検討し始めることができます。

もちろん、このリストは網羅的なものではありません。当社の計画は、GitHub ロードマップPlay 2.10 マイルストーンで確認できます。

次へ: 移行ガイド


このドキュメントに誤りを見つけましたか?このページのソースコードはこちらにあります。ドキュメントガイドラインをお読みになった後、プルリクエストにご自由に貢献ください。ご質問やアドバイスがありましたら、コミュニティフォーラムでコミュニティとの会話を開始してください。