diff --git a/manual/Home.md b/manual/Home.md
index 80009344..b0eea673 100644
--- a/manual/Home.md
+++ b/manual/Home.md
@@ -1,35 +1,40 @@
-
+
# Play %PLAY_VERSION% ドキュメント
->Play は、現代の web アプリケーション開発に必要なコンポーネント及び API を統合した生産性の高い Java と Scala の web アプリケーションフレームワークです。
+
+> Play は、現代の web アプリケーション開発に必要なコンポーネント及び API を統合した生産性の高い Java と Scala の web アプリケーションフレームワークです。
>
-> Play の特徴は、ライトウェイト、ステートレス、web フレンドリーなアーキテクチャであること、機能予測のしやすさです。また、Iteratee IO をベースにしたリアクティブモデルのおかげで、スケーラブルなアプリケーションでも CPU、メモリ、スレッドなどのリソース消費が最小限になっています。
+> Play の特徴は、ライトウェイト、ステートレス、web フレンドリーなアーキテクチャであること、機能予測のしやすさです。また、Akka Streamsをベースにしたリアクティブモデルのおかげで、スケーラブルなアプリケーションでも CPU、メモリ、スレッドなどのリソース消費が最小限になっています。
+
+
+## Latest release
-- [[Play 2.4 の変更点|Highlights24]] / [[Play 2.4 移行ガイド|Migration24]]
-- [[Play 2.3 の変更点|Highlights23]] / [[Play 2.3 移行ガイド|Migration23]]
-- [[Play 2.2 の変更点|Highlights22]] / [[Play 2.2 移行ガイド|Migration22]]
-- [[Play 2.1 の変更点|Highlights21]] / [[Play 2.1 移行ガイド|Migration21]]
+- [[Play2.6の変更点|Highlights26]]
+- [[Play2.6移行ガイド|Migration26]]
+- [[その他のPlayのリリース|Releases]]
@toc@
-## モジュールとプラグイン
+
+##モジュール
-[[一時的なモジュールディレクトリ | ModuleDirectory]]
+[[モジュールディレクトリ|ModuleDirectory]]
diff --git a/manual/LatestRelease.md b/manual/LatestRelease.md
new file mode 100644
index 00000000..96aa1c3c
--- /dev/null
+++ b/manual/LatestRelease.md
@@ -0,0 +1,8 @@
+
+# Latest release
+
+Learn more about the latest Play release. You can download Play releases [here](https://www.playframework.com/download).
+
+- [[What's new in Play 2.6?|Highlights26]]
+- [[Play 2.6 Migration Guide|Migration26]]
+- [[Other Play releases|Releases]]
diff --git a/manual/ModuleDirectory.md b/manual/ModuleDirectory.md
index 9fee9424..b124bc79 100644
--- a/manual/ModuleDirectory.md
+++ b/manual/ModuleDirectory.md
@@ -1,888 +1,304 @@
-
-
-# Play モジュール
-
-
-> ここはモジュール一覧が Play ウェブサイト上で登録できるようになるまでの、一時的な公開場所です。
-
-
-> モジュールを作成するための手順を説明したブログ記事が [objectify.be](http://www.objectify.be/wordpress/?p=363) にあります。
-
-
-## Airbrake.io notifier
-
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** airbrake.io に例外通知を送信する
-
-
+# Play modules
-* **Website:**
-* **Documentation:**
-* **Short description:** SES (Simple Email Service) API wrapper for Play
--->
-## Amazon SES モジュール (Scala)
+Play uses public modules to augment built-in functionality.
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 用 SES (Simple Email Service) API ラッパー
+To create your own public module or to migrate from a `play.api.Plugin`, please see [[ScalaPlayModules]] or [[JavaPlayModules]].
-
-## Amazon S3 モジュール (Scala)
+### swagger-play
+* **Website:**
+* **Short description:** Generate a Swagger API spec from your Play routes file and Swagger annotations
+
+### iheartradio/play-swagger
+* **Website:**
+* **Short description:** Write a Swagger spec in your routes file
+
+### zalando/play-swagger
+* **Website:**
+* **Short description:** Generate Play code from a Swagger spec
+
+### mohiva/swagger-codegen-play-scala
+* **Website:**
+* **Short description:** Swagger client generator which is based on the PlayWS library
+
+## Assets
+
+### play2-sprites
+* **Website:**
+* **Short description:** play2-sprites is an sbt plugin that generates sprites from images.
+
+### Sass Plugin
+* **Website:**
+* **Short description:** Asset handling for [Sass](http://sass-lang.com/) files
+
+### Typescript Plugin
+* **Website:**
+* **Short description:** A plugin for sbt that uses sbt-web to compile typescript resources
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 用 S3 (Simple Storage Service) API ラッパー
+### play-webpack Plugin
+* **Website:**
+* **Short description:** A plugin for sbt to handle webpack generated assets and library to render Javascript on the server with Java's nashorn engine.
-
-## Amf モジュール (Scala)
+### Silhouette (Scala)
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 用 AMF (ActionScript Message Format) ラッパー
+* **Website:**
+* **Documentation:**
+* **Short description:** An authentication library that supports several authentication methods, including OAuth1, OAuth2, OpenID, CAS, Credentials, Basic Authentication, Two Factor Authentication or custom authentication schemes.
-
-## Authentication and Authorization モジュール (Scala)
-* **ウェブサイト:**
-* **ドキュメント (英):**
-* **ドキュメント (日):**
-* **概要:** 認証や認可の手段を提供するモジュール
-* 2.1-SNAPSHOT サポートもあります:
+### Play! Authenticate (Java)
-
-## Authenticity Token モジュール
+### SecureSocial (Java and Scala)
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 1 の authenticity token を復活させ、 CSRF 攻撃を回避する手段を提供する。
+* **Website:**
+* **Short description:** An authentication module supporting OAuth, OAuth2, OpenID, Username/Password and custom authentication schemes.
-
-## ClojureScript プラグイン
+### Flyway plugin
-* **ウェブサイト:** (ドキュメント、コード)
-* **概要:** ClojureScript アサートファイルを JavaScript にコンパイルする
+* **Website:**
+* **Documentation:**
+* **Short Description:** Supports database migration with Flyway.
-
-## Cloudfront モジュール (Scala)
+### MongoDB Morphia Plugin (Java)
+* **Website (docs, sample):**
+* **Short description:** Provides managed MongoDB access and object mapping using [Morphia](http://morphiaorg.github.io/morphia/)
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play アプリケーションと Cloudfront CDN との統合を補助するモジュール
+### MongoDB ReactiveMongo Plugin (Scala)
+* **Website (docs, sample):**
+* **Short description:** Provides a Play 2.x module for ReactiveMongo, asynchronous and reactive driver for MongoDB.
-
-## Currency Converter (Java)
+### Play-Slick
+* **Website (docs, sample):**
+* **Short description:** This plugin makes Slick a first-class citizen of Play.
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 用の通貨変換器。現在のレートを取得するためにウェブサービスを利用する。
+### Redis Plugin (Java and Scala)
+* **Website (docs, sample):**
+* **Short description:** Provides a redis based cache implementation, also lets you use Redis specific APIs
-
-## Deadbolt 2 プラグイン
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** Deadbolt は、AND/OR/NOT の簡単なシンタックスを使って、特定のコントローラメソッドやビューのパーツにアクセス権を定義する認可メカニズムです。
-
-
-## DDSL プラグイン - Dynamic Distributed Service Locator
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** DDSL は、ZooKeeper を使用して、インハウスあるいは EC2 やJoyent を利用した独自の動的な "プライベートクラウド" を簡単に構築できるようにします。
-
-
-## Dust プラグイン
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** クライアントサイドテンプレート言語 Dust のサポート
-
-
-## Google Closure Template プラグイン
-* **ウェブサイト (ドキュメント、サンプル):** [https://github.com/gawkermedia/play2-closure](https://github.com/gawkermedia/play2-closure)
-* **概要:** Google Closure テンプレートのサポート
-
-
-## Elasticsearch
-
-* **ウェブサイト:**
-* **ドキュメント:**
-* **リポジトリ:**
-* **概要:** 組み込みの ElasticSearch サーバまたはリモートノード内のオブジェクトをインデクシング/リクエストします
-
-
-## Ember.js
-
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** ember.js/handlebars テンプレートのプリコンパイルのサポート
-
-
-## funcy - Page Driven Functional Tests (Java)
-
-* **ウェブサイト:**
-* **ドキュメント:**
-* **リポジトリ:**
-* **概要:** Page Driver クラスを用いた機能テストを簡単に記述できるようにする
-
-
-## FolderMessages プラグイン
+* **Website:**
+* **Short description:** Provides yet another database access API for Play
-* **ウェブサイト:**
-* **概要:** ローカライズ用の messages ファイルを分割できるようにして、別々のファイルとしてに管理できるようにする
+### Redis Cache Plugin (Java and Scala)
-
-## Flyway プラグイン
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Flyway を使用したデータベースマイグレーション
-
-## Geolocation (Java)
+### WAR Module
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** IP ベースの地理的位置情報取得モジュール
+* **Website:**
+* **Documentation:**
+* **Short description:** Allow to package Play! 2.x applications into standard WAR packages.
-
-## Google's HTML Compressor (Java and Scala)
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 2 用の Google 製 HTML 圧縮器
-
-
-## Groovy Templates プラグイン
-
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 1 と Play 2 に対応した Groovy テンプレートエンジン
-
-
-## Groovy Templates プラグイン - gt-engine-play2
-
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 1 と Play 2 に対応した Groovy テンプレートエンジン。Play 1 の "Faster Groovy Templates" モジュールで使用された gt-engine which を採用している
-* **Samples:**
-
-
-## Guice プラグイン (Java and Scala)
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** Guice による DI
-
-
-## HTML5 Tags モジュール (Java and Scala)
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** モデルの制約 (required, email pattern, max|min lentgh 等) や特定の input フィールド (date, telephone number, url 等) をもとに、クライアントサイドでバリデーションできるようにする。
-
-
-## InputValidator (Scala)
-
-* **ウェブサイト:**
-* **概要:** Play 用のシンプルなバリデーション API を提供する
-
-
-## JackRabbit プラグイン (Java and Scala)
-* **ウェブサイト (ドキュメント、サンプル):** [JackRabbit Plugin GitHub](https://github.com/sgougi/play21-jackrabbit-plugin)
-* **概要:** Play 2 用 Apache JackRabbit プラグイン
-
-
-## Japid モジュール
-
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 用の Japid java テンプレートを提供する
-
-
-## JsMessages
+## Page Rendering
-* **ウェブサイト:**
-* **概要:** ローカライズされた messages をクライアントサイドで算出できるようにする
+### Play Pagelets
+* **Website:**
+* **Short Description:** A Module for the Play Framework to build resilient and modular Play applications in an elegant and concise manner.
+* **Seed project:**
-
-## JSON minification プラグイン
+## Localization
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** JSON を整形・圧縮する
+### FolderMessages plugin
-
-## JSONP filter
+### JsMessages
-* **ウェブサイト:**
-* **概要:** 既存の HTTP API で JSONP を有効化する
+* **Website:**
+* **Short description:** Allows to compute localized messages on client side.
-
-## Lessc プラグイン
+* **Website:**
+* **Documentation:**
+* **Short description:** Provides type safety for the project's messages.
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Node を経由して [Less](http://lesscss.org/) をコマンドラインでコンパイルできるようにする
+### Play I18n HOCON
-
-## Liquibase Module
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** アプリケーション起動時に [Liquibase](http://www.liquibase.org/) データベースマイグレーションを実行する
+## Performance
-
-## Manual Dependency Injection プラグイン (Java and Scala)
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** 手動で依存性注入できるようにする
+### Google's HTML Compressor (Java and Scala)
+* **Website:**
+* **Documentation:**
+* **Short description:** Google's HTML Compressor for Play 2.
-
-## Memcached プラグイン
-* **ウェブサイト:**
-* **概要:** memcached をベースにキャッシュを実装できるようにする
+## Task Schedulers
-
-## Messages Compiler プラグイン (Scala)
+* **Website**:
+* **Documentation**:
+* **Short description**: Quartz Extension and utilities for cron-style scheduling in Akka
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** プロジェクトの messages を型安全にする
+### play-akkjobs
-
-## MongoDB Jackson Mapper プラグイン (Java)
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** MongoDB への管理されたアクセスと Jackson アノテーションを使用したオブジェクトマッピングを提供する
+## Settings
-
-## MongoDB Jongo プラグイン (Java)
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** MongoDB への管理されたアクセスと [Jongo](http://jongo.org/) を使用したオブジェクトマッピング
-
-
-## MongoDB Morphia プラグイン (Java)
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** MongoDB への管理されたアクセスと Morphia を使用したオブジェクトマッピング
-
-
-## MongoDB Salat, Casbah プラグイン (Scala)
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** MongoDB への管理されたアクセスと Salat と Casbah を使用したオブジェクトマッピング
-
-
-## Mountable routing
-
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:**
-
-
-## Mustache (Java,Scala)
-
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Mustache テンプレートのサポート
-
-
-## Native Packaging Module
-
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 2 アプリケーションを標準的システムパッケージ (deb/rpm/msi) としてパッケージできるようにする
-
-
-## NINA (Scala)
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** SQL データベースに対し、特に select のようなクエリについて、型安全に発行できるようにする
-
-
-## Origami: OrientDB O/G Mapper (Java and Scala)
-* **ウェブサイト (ドキュメント、サンプル):** [Origami Plugin GitHub](https://github.com/sgougi/play21-origami-plugin)
-* **概要:** Origami プラグインは、Play 2 Java の OrientDB 用 O/G マッパです。
-
-
-## PDF モジュール (Java)
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** HTML テンプレートから PDF を生成します
+### PlayFOP (Java and Scala)
-
-## Play! Authenticate (Java)
+### Play-Bootstrap (Java and Scala)
+* **Website:**
+* **Repository:**
+* **Short description:** A library for Bootstrap that gives you an out-of-the-box solution with a set of input helpers and field constructors.
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** 高度にカスタマイズ可能な Play 用認証モジュール
+### Thymeleaf module (Scala)
+* **Website:**
+* **Documentation:**
+* **Short description:** Allows to use [Thymeleaf](https://www.thymeleaf.org/) template engine as an alternative
+to Twirl
-
-## play2-sprites
-* **ウェブサイト:**
-* **概要:** play2-sprites は画像からスプライトを生成する sbt プラグインです。
-
-
-## Play-Bootstrap3 (Java and Scala)
-* **ウェブサイト:**
-* **ドキュメント:**
-* **リポジトリ:**
-* **概要:** Play 2.4 で Twitter Bootstrap 3 の HTML コードをレンダリングするための input ヘルパーあるいはフィールドのコンストラクタをまとめました
-
-
-## play-jaxrs (Java)
-* **ウェブサイト (ドキュメント、サンプル):** [play-jaxrs](https://github.com/pk11/play-jaxrs/)
-* **概要:** Play Java 用 JAX-RS ルータプラグイン
-
-
-## Play-pac4j (Java and Scala)
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** OAuth/CAS/OpenID/HTTP 認証とユーザープロフィールの取得をサポートする Play Scala/Java クライアント
-
-
-## Play Plovr プラグイン
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** Play に Closure コンパイラと Closure ライブラリを追加する
-
-
-## Play-Slick
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** Slick を Play の第一級オブジェクトにする
+### Handlebars templates (Java and Scala)
+
+* **Website:**
+* **Documentation:**
+* **Short description:** [Handlebars](http://handlebarsjs.com/) templates based on [Java port](https://github.com/jknack/handlebars.java) of handlebars with special handlers for Play Framework.
-
-## Pusher
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play アプリケーションと Pusher Service サービスとの通信を容易にする
-
-
-## Play Dok
-
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play アプリケーションと Fukdok PDF テンプレートサービスとの統合を容易にする
-
-
-## Qunit (Java)
-
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** JavaScript ユニットテストスイート
-
-
-## Redis プラグイン (Java and Scala)
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** Redis ベースのキャッシュ実装を提供し、Redis 独自 API も使用できるようにする
-
-
-## Swaggerkit (Scala)
-* **ウェブサイト (ドキュメント、サンプル、コード):**
-* **概要:** JSON REST API の [Swagger](http://swagger.io/) 仕様書をきれいに出力できるようにする
-
-
-## Emailer プラグイン (Java and Scala)
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** apache commons-email をベースとした emailer を提供する
-
-
-## Roy Compiled Asset プラグイン (Ray)
-* **ウェブサイト:**
-* **ブログ記事:**
-* **概要:** [Roy](http://roy.brianmckenna.org/) ファイルを JavaScript にコンパイルする
-
-
-## Sass プラグイン
-* **ウェブサイト:**
-* **概要:** [Sass](http://sass-lang.com/) ファイルのアサートハンドリング
-
-
-## ScalikeJDBC プラグイン (Scala)
-* **ウェブサイト:**
-* **概要:** Play の「もう一つのデータベースアクセス API 」を提供する
+### Geolocation (Java)
-
-## SecureSocial (Java and Scala)
+### JSONP filter
-* **ウェブサイト:**
-* **概要:** OAuth, OAuth2, OpenID, Username/Password, そして独自の認証スキームをサポートする認証モジュール
+* **Website:**
+* **Short description:** Enables JSONP on your existing HTTP API.
-
-## Silhouette (Scala)
+* **Website:**
+* **Documentation:**
+* **Short description:** Automatic [sitemaps](https://www.sitemaps.org/) generator for Play
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** OAuth1, OAuth2, OpenID, Credentials, Basic認証、二段階認証、カスタム認証スキームなどを提供する認証ライブラリ
+### play-guard (Scala)
-
-## Sitemap Generator (Java)
-
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 用 [sitemaps](http://www.sitemaps.org/) 自動生成
-
-
-## Snapshot プラグイン (Java and Scala)
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** Google が [こちら](https://developers.google.com/webmasters/ajax-crawling/docs/html-snapshot) で説明している、HtmlUnit を使った hasg bang スナップショット機能を提供する
-
-
-## socket.io.play (scala only, pre-alpha)
-
-* **ウェブサイト:**
-* **ドキュメント:**
-
-
-## Stateless client authentication (Scala)
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** サーバサイドの状態なしに (状態はクライアントが保持する) 必須あるいはオプションの認証を提供する
-
-
-## Statsd プラグイン (Java and Scala)
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** statsd クライアントを提供する
-
-
-## Stylus プラグイン
-
-* **ウェブサイト:**
-* **概要:** [Stylus](https://github.com/learnboost/stylus) による CSS コンパイルのサポート
-
-
-## TinkerPop Frames O/G Mapper プラグイン (Java)
-* **ウェブサイト (ドキュメント、サンプル):** GitHub: [Frames-Neo4j Plugin](https://github.com/sgougi/play21-frames-neo4j-plugin) / [Frames-OrientDB Plugin](https://github.com/sgougi/play21-frames-orientdb-plugin) / [Frames-Titan Plugin](https://github.com/sgougi/play21-frames-titan-plugin)
-* **概要:** GraphDBs 用 Java O/G マッパ
-
-
-## Typesafe util プラグイン (Scala)
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** リクエストヘッダベースのセキュリティ・シンタックスシュガーを提供するプラグイン
-
-
-## Typesafe SbtGoodies プラグイン
-* **ウェブサイト (ドキュメント、サンプル):**
-* **概要:** 追加の sbt コマンドを提供するプラグイン
-
-
-## TypeScript プラグイン
-* **ウェブサイト:**
-* **概要:** [TypeScript](http://www.typescriptlang.org/) ファイルを扱う
-
-
-## WAR Module
+## Cloud services
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 2.x アプリケーションを標準 WAR パッケージにまとめる
+### Amazon SES module (Scala)
-
-## XForward モジュール
+### Amazon S3 module (Scala)
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 1 のプロキシフォワーディング設定を Play 2 に復活させる
+* **Website:**
+* **Documentation:**
+* **Short description:** S3 (Simple Storage Service) API wrapper for Play
-
-## XWiki Rendering モジュール (Scala)
+* **Website:**
+* **Documentation:**
+* **Short description:** A reactive module for the Benji library, providing an Object storage DSL (AWS/Ceph S3, Google Cloud Storage).
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Play 用 XWiki レンダリングフレームワーク
+### Pusher
+* **Website:**
+* **Documentation:**
+* **Short description:** Easily interact with the Pusher Service within your Play application.
-
-## Thymeleaf モジュール (Scala)
-* **ウェブサイト:**
-* **ドキュメント:**
-* **概要:** Twirl のかわりに [Thymeleaf](http://www.thymeleaf.org/) テンプレートエンジンを使えるようにする
+### Push Notifications module (Java)
+* **Website:**
+* **Documentation:**
+* **Short description:** A stupid-simple module for creating, batching, queuing and sending push notifications.
diff --git a/manual/about/Philosophy.md b/manual/about/Philosophy.md
index 5afb18b1..2c2c3981 100644
--- a/manual/about/Philosophy.md
+++ b/manual/about/Philosophy.md
@@ -1,4 +1,4 @@
-
+
@@ -9,147 +9,64 @@ Since 2007, we have been working on making Java web application development easi
-->
2007 年以来、私たちは Java での web アプリケーション の開発を容易なものにしようとしてきました。Play は、 Zenexity (現在は [Zengularity](http://zengularity.com/)) における内部的なプロジェクトとしてスタートし、私たちの web プロジェクトの進め方に強く影響されてきました。つまり、開発者の生産性に焦点を当て、 web のアーキテクチャを尊重し、初めからパッケージング規約に対して斬新なやり方を採用してきたのです - そうすることが理にかなっている場合には、いわゆる JEE のベストプラクティスをも破ってきました。
-
-2009 年に、私たちはこれらのアイデアを、オープンソースプロジェクトとしてコミュニティと共有することを決断しました。即座に返されたフィードバックは極めてポジティブなものであり、このプロジェクトは大きな関心を引きつけました。今日 - 2 年間の活発な開発を経て - Play にはいくつかのバージョンができ、10,000 人以上の参加者からなる活発なコミュニティが存在し、世界中で実際に使われているアプリケーションの数は増え続けています。
-世界中に対してプロジェクトを解放するということは、確かにより多くのフィードバックを得られるということではありますが、それはまた、新たなユースケースに出会ってそこから学ぶことや、新たな機能が必要になることや、 元々の設計や前提の下では考慮されていなかったバグが明らかになることでもあります。オープンソースプロジェクトとして Play に取り組んできた 2 年の間に、私たちはこういったすべての問題を修復し、加えて広範囲なシナリオをサポートするための新たな機能を統合してきました。 Play のプロジェクトが成長するにつれて、私たちは Play のコミュニティと、私たち自身の経験から学びました - Play は、どんどん複雑で、多様なプロジェクトで使われるようになってきたのです。
+2009 年に、私たちはこれらのアイデアを、オープンソースプロジェクトとしてコミュニティと共有することを決断しました。即座に返されたフィードバックは極めてポジティブなものであり、このプロジェクトは大きな関心を引きつけました。今日 - 幾年かの活発でパブリックな開発を経て - Play にはいくつかのバージョンができ、10,000 人以上の参加者からなる活発なコミュニティが存在し、世界中で実際に使われているアプリケーションの数は増え続けています。
+
+Opening a project to the world certainly means more feedback, but it also means discovering and learning about new use cases, required features and unearthing bugs that were not specifically considered in the original design and its assumptions. During these years of work on Play as an open source project we have worked to fix this kind of issues, as well as to integrate new features to support a wider range of scenarios. As the project has grown, we have learned a lot from our community and from our own experience - using Play in more and more complex and varied projects.
-
-一方、技術と web の進化の歩みはとどまることを知りません。web は、あらゆるアプリケーションの中心となりました。 HTML, CSS, JavaScript の技術は、急速に発展してきましたーサーバーサイドのフレームワークがついていくことはほとんど不可能なほどです。web のアーキテクチャは、総体として、リアルタイム処理の方向へ急速に向かっており、今日のプロジェクト群に求められるようになった事項からは、データストア技術として SQL を唯一のものとするわけにはいかなくなっていることが分かります。プログラミング言語のレベルにおいては、私たちは、一般的になってきた Scala を含むいくつかの JVM 言語に関連する、後々まで記憶されるような変化の目撃者となりました。
-
-それこそが、新時代の web フレームワーク、 Play 2 を開発した理由です。
-
-## 非同期プログラミングの構築
-
-今日の web アプリケーションは、これまで以上にリアルタイムデータの並行処理を統合するようになってきており、 web フレームワークには完全な非同期 HTTP プログラミングモデルをサポートすることが求められます。 Play はまず、短期間に処理される大量のリクエストを処理する、クラシックな web アプリケーションを扱うように設計されました。しかし今日では、Comet、長期間のポーリング、WebSockets を通じて、接続が保持され続けるコネクションを処理するため、イベントモデルへと進むべきです。
-
-Play 2 は、最初からすべてのリクエストが潜在的に長期間保持されるものと見なして設計されています。しかしそれだけではなく、私たちには、長時間にわたって処理されるタスクのスケジューリングと実行を扱う、強力な方法も必要です。 今日、並列度が非常に高いシステムを扱うモデルとしては、Actor ベースのモデルが最良であること、そして Java と Scala の双方で利用可能な Actor ベースのモデルの実装として、Akka が最良のものであることは、疑問の余地がありません - これが、Akka を使う理由です。Play 2 は Play アプリケーションで [Akka](http://akka.io/) をネイティブにサポートし、高度な分散システムを書くことができるようにします。
+Play 2 is architected from the start under the assumption that every request is potentially long-lived. But that’s not all: we also need a powerful way to schedule and run long-running tasks. The Actor-based model is unquestionably the best model today to handle highly concurrent systems, and the best implementation of that model available for both Java and Scala is Akka - so it’s going in. Play 2 provides native [Akka](https://akka.io/) support for Play applications, making it possible to write highly-distributed systems.
-
-## 型安全性へのフォーカス
-
-Play のアプリケーションを書くための言語として 静的型付け言語を使う利点の一つは、コンパイラがコードのある部分をチェックできるという点にあります。これは、開発プロセスの早期にミスを検出するのに有効であるのみならず、多くの開発者が参加する大規模なプロジェクトでの作業をとても容易にしてくれます。
-
-Play 2 の中に Scala を追加することで、私たちは間違いなく、コンパイラによるさらに強力な保障という利点を得ることになります - しかし、それでもまだ十分ではありません。Play 1.x では、テンプレートシステムは動的なものであり、 Groovy に基づくもので、コンパイラにできることはそれほどありませんでした。その結果、テンプレートで発生するエラーは、実行時にしか検出できなかったのです。これは、コントローラとの間を取り持つコードの検証についても同じことが言えました。
-
-私たちは Play 2 において、コードのほとんどをコンパイル時にチェックさせるという考え方をさらに推し進めたいと強く考えています。そのため、私たちは Play のアプリケーションのデフォルトとして、 Scala ベースのテンプレートエンジンを使うことに決めました - これは、Java をメインのプログラミング言語として使う開発者にとっても、です。ただしだからといって、Play 1.x でテンプレートを書くために、Groovy を本当に知っていることが必要だったわけではないのと同様に、Scala のエキスパートにならなければ Play 2 でテンプレートを書くことができないということではありません。
-
-Scala が主に使われるのは、Java のシンタックスに極めて近いシンタックスを使って、必要な情報を表示するのにオブジェクトグラフをたどっていくためです。とはいえ、Scala の持つパワーを生かして高度に抽象化されたテンプレートを書きたいなら、式指向で関数型である Scala が、どれほどテンプレートエンジンにぴったりなのかは、すぐに理解できることでしょう。
-
-そして、これはテンプレートエンジンにだけ言えることではありません。ルーティングのシステムもまた、完全に型が検査されることになります。Play 2 は、ルートに関するすべての記述をチェックし、リバースルートの部分も含めて、すべてにおいて整合性が保たれているかどうかを検証します。
-
-完全にコンパイルが行われることの嬉しい副作用として、テンプレートとルートファイルのパッケージ化と再利用が容易になることと、これらの部分の実行時のパフォーマンスの大幅な向上が見込めるということもあります。
-
-## Java 及び Scala のネイティブサポート
-
-Play 1.1 から、Play のアプリケーションを書くのにプログラミング言語 Scala を使用する可能性を、私たちは探り始めました。この作業は、まずフレームワークそのものに影響を与えることなく、自由に試せるような外部モジュールとして導入されました。
-
-Scala を適切に Java ベースのフレームワークに統合することは容易なことではありません。Scala が持つ Java との互換性を考慮すれば、単純に Scala のシンタックスを Java のシンタックスの代わりに使う形で、まず単純に素早く統合してしまうことは可能です。しかしこれは間違いなく、Scala を利用する上で最適な方法ではありません。 Scala は、真のオブジェクト指向と関数型プログラミングを混合したものです。Scala の本当のパワーを解放するには、Play のフレームワークの API の多くを再検討しなければなりません。
-
-今では、私たちは個別のモジュールとして Scala をサポートするやり方の限界点に到達しています。私たちが Play 1.x で行った、初期の設計における選択は、Java のリフレクションAPIとバイトコードの操作に強く依存しており、Play の内部の重要な部分のいくつかについて完全に再検討し直さなければ、これ以上の進歩は難しくなっていました。一方で、私たちは Scala モジュールのために、新たな型安全テンプレートエンジンや、まったく新しい SQL アクセスコンポーネントである [Anorm](https://github.com/playframework/anorm) といった、複数の素晴らしいコンポーネントを作成していました。そこで私たちは、 Scala の持つパワーを Play で完全に解放するために、Scala のサポートを個別のモジュールから、Play 2 のコアへ移すことを決断しました。この Play 2 のコアは、初めからプログラミング言語として Scala をネイティブにサポートするよう設計されることになります。
-
-一方で、Java に対するサポートが Play 2 から弱くなることはまったくありません。むしろ、完全にその反対なのです。 Play 2 のビルドは、Java の開発者に対し、開発の体験を拡張する機会を提供します。
-
-## 強力なビルドシステム
-
-私たちは初めから、Play のアプリケーションの実行、コンパイル、デプロイについて、斬新な方法を選択してきました。当初、私たちの採った方法は、難解な設計に見えたかも知れません - しかし、標準的な Servlet API の代わりに非同期 HTTP API を提供し、ライブコンパイルと開発中のソースコードのリロードによって短いフィードバックサイクルを提供し、斬新なパッケージングのアプローチを推進することは、極めて重要なことだったのです。その結果として、Play が標準的な JEE の規約に従うことは難しくなりました。
-
-今日では、コンテナレスデプロイメントの概念は、Javaの世界において非常に広く受け入れられるようになってきました。この設計上の選択によって、Play framework は Heroku のようなプラットフォームにおいてネイティブに動作できるようになりました。私たちは、[Heroku](https://www.heroku.com/) によって紹介されたモデルは、エラスティックな PaaS プラットフォームにおける Java アプリケーションのデプロイメントの未来だと考えています。
+Today, this idea of container-less deployment is increasingly accepted in the Java world. It’s a design choice that has allowed the Play Framework to run natively on platforms like [Heroku](https://www.heroku.com/), which introduced a model that we consider the future of Java application deployment on elastic PaaS platforms.
-
-一方で、既存の Java のビルドシステムは、この新しいアプローチをサポートするには、柔軟性が不足していました。私たちは、Play のアプリケーションを実行し、デプロイするための単純明快なツールを提供したいと考えていたことから、Play 1.x では ビルドとデプロイメントのタスクのすべてを処理するために、Python スクリプトの集合体を作り上げました。
-
-しかし、ビルドのプロセスのカスタマイズや、企業内の既存のビルドシステムとの統合が求められる、よりエンタープライズ規模のプロジェクトで Play を使っている開発者の方々は、少々困っていました。私たちが Play 1.x で提供していた Python のスクリプト群は、完全な機能を完備したビルドシステムではまったくありませんでしたし、カスタマイズも容易ではありませんでした。これが、私たちが Play 2 でさらに強力なビルドシステムへ舵を切ることを決めた理由です。
-
-Play 独自の規約をサポートでき、Java と Scala のプロジェクトをビルドできるだけの柔軟性を持った、現代的なビルドツールが必要だったことから、私たちは [sbt](http://www.scala-sbt.org/) を Play 2 に統合することにしました。ただしこれによって、既存の Play のビルドのシンプルさに満足しているユーザーが脅かされることがあってはなりません。私たちは [Activator](https://www.typesafe.com/get-started) を使って拡張性のあるモデルの上に `activator new`, `run`, `start` などのシンプルなコマンドを提供していますし、アプリケーションのビルドやデプロイの方法を変更する必要がある場合は、Play のプロジェクトは標準的な sbt プロジェクトなので、カスタマイズや特殊な要求への適用に応えるだけのあらゆるパワーを活用できるのです。
+Since we need a modern build tool, flexible enough to support Play original conventions and able to build Java and Scala projects, we have chosen to integrate [sbt](https://www.scala-sbt.org/) in Play 2. sbt is the de facto build tool for Scala and is increasingly accepted in the Java community as well.
-
-これはまた、Play 2 はインストール直後から、Maven との統合がこれまでよりもうまくできているということでもあり、プロジェクトをシンプルな jar ファイルの集合体としてパッケージ化し、任意のリポジトリへ公開できるということでもあり、さらには依存しているいかなる標準的な Java あるいは Scala ライブラリが開発中の状態であっても、ライブコンパイルやリローディングが可能だということでもあります。
-
-## データストアとモデルの統合
-
-データストアは、もはや「SQL データベース」の同義語ではありませんし、おそらくはこれまでもそうではありませんでした。データストアの興味深いモデルは、数多くのものが広く使われるようになり、様々なシナリオにおいて、様々な特徴が提供されてきました。そのため、Play のような web フレームワークにとっては、開発者がどのようなデータストアを利用するのか、明確な推測をすることが難しくなってきたのです。Play における汎用モデルの考え方は、単一の API でこういった技術のすべてを抽象化するのはほとんど不可能である以上、もはや意味を成さないものになってしまっています。
-
-私たちは Play 2 で、どのようなデータストアドライバ、ORM あるいはその他のデータベースアクセスライブラリも、特にこのフレームワークに統合することなく、容易に利用できるようにしたいと考えています。私たちは単に、コネクションのバインドの管理のような、一般的な技術的課題を扱うための、最小限のヘルパーを提供するようにしたいのです。とはいえ、私たちはまた、特殊な要求を持たないユーザーがクラシックなデータベースへアクセスするためのデフォルトのツールをバンドルすることで、 Play フレームワークのフルスタックという性格も保ち続けたいと思っています。それこそが、 Play 2 が [Ebean](http://ebean-orm.github.io/), JPA, Anorm といったビルドインのリレーショナルデータベースアクセスライブラリを同梱している理由です。
\ No newline at end of file
+In Play 2, we wanted to make it really easy to use any data store driver, ORM, or any other database access library without any special integration with the web framework. We simply want to offer a minimal set of helpers to handle common technical issues, like managing the connection bounds. We also want, however, to maintain the full-stack aspect of Play Framework by bundling default tools to access classical databases for users WHO don’t have specialized needs, and that’s why Play 2 comes with built-in relational database access libraries such as [Ebean](http://ebean-orm.github.io/), JPA and Anorm.
diff --git a/manual/about/PlayUserGroups.md b/manual/about/PlayUserGroups.md
index 672893a7..4d25e7f6 100644
--- a/manual/about/PlayUserGroups.md
+++ b/manual/about/PlayUserGroups.md
@@ -1,87 +1,44 @@
-
-
+
# Play User Groups
--->
-# Play ユーザーグループ
-
-## ニューヨーク
-
-http://www.meetup.com/Play-NYC/
-
-
-## ベルリン
-http://www.meetup.com/Play-Berlin-Brandenburg/
+https://www.meetup.com/Play-NYC/
-
-## ケルン
-
-### Scala ユーザーグループ ケルン/ボン
-
-*(Play について話し合い, プレゼンテーションを行いました。)*
[Xing](https://www.xing.com/communities/groups/scala-user-group-koeln-bonn-1035441) / [Twitter](https://twitter.com/scalacgn)
-
-## ブエノスアイレス
+## Vienna - AUSTRIA
-http://www.meetup.com/play-argentina/
+https://www.meetup.com/PlayFramework-Wien/
-
-## ストックホルム
+## Buenos Aires
-http://www.meetup.com/play-stockholm/
+https://www.meetup.com/play-argentina/
-
-## ベルギー
-http://www.play-be.org
+
-
-## 日本
-* http://www.playframework-ja.org/
* https://groups.google.com/forum/?fromgroups#!forum/play_ja
-
-## 韓国
-
-#### 韓国 Play! ユーザグループ
* [Facebook](https://www.facebook.com/groups/playuser)
* [Github](https://github.com/kpug)
* [Slack](https://kpug.slack.com)
-
-
-## ニューデリー - インド
-http://www.meetup.com/Reactive-Application-Programmers-in-Delhi-NCR/
+https://www.meetup.com/Reactive-Application-Programmers-in-Delhi-NCR/
diff --git a/manual/about/index.toc b/manual/about/index.toc
index 683f9525..abe48d35 100644
--- a/manual/about/index.toc
+++ b/manual/about/index.toc
@@ -1,2 +1,2 @@
-Philosophy:Play の哲学
-PlayUserGroups:Play ユーザグループ
+Philosophy:Playの哲学
+PlayUserGroups:Playユーザグループ
\ No newline at end of file
diff --git a/manual/detailedTopics/assets/Assets.md b/manual/detailedTopics/assets/Assets.md
deleted file mode 100644
index aeb62c3d..00000000
--- a/manual/detailedTopics/assets/Assets.md
+++ /dev/null
@@ -1,310 +0,0 @@
-
-
-# 公開アセットを扱う
-
-
-この節は JavaScript, CSS と画像などのアプリケーションの静的リソースの提供をカバーします。
-
-
-Play で public リソースを提供することは、他の HTTP リクエストにサービスを提供することと同じです。コントローラ/アクションのパスが使う通常のリソースと同じルーティングを使って、クライアントに CSS, JavaScript や画像ファイルを配布します。
-
-
-## public/ フォルダ
-
-
-規約により、公開アセットはアプリケーションの `public` フォルダに格納されます。このフォルダは好きなように構成できます。以下の構成がおすすめです:
-
-```
-public
- └ javascripts
- └ stylesheets
- └ images
-```
-
-
-このフォルダ構成に従えば簡単に始められますが、どのように動作するか理解している場合は、自由に変更できます。
-
-
-## WebJars
-
-
-[WebJars](http://www.webjars.org/) は、Activator や sbt の一部となっている、便利で規約化されたパッケージング機構を提供します。例えば、ビルドファイルに以下のように依存性を追加するだけで、ポピュラーな [Bootstrap ライブラリ](http://getbootstrap.com/) を使うことができます。
-
-```scala
-libraryDependencies += "org.webjars" % "bootstrap" % "3.3.4"
-```
-
-
-利便性のため、WebJar は依存性を公開アセットフォルダから見た `lib` 関連パスに自動的に展開します。例えば、[RequireJs](http://requirejs.org/) の依存性を宣言している場合、以下のようにしてビューから参照することができます:
-
-```html
-
-```
-
-
-`lib/requirejs/require.js` パスに注目してください。この `lib` フォルダは展開された WebJar アセットを示し、`requirejs` フォルダは WebJar アーティファクト ID に対応していて、そして `require.js` が、この WebJar のルートにある要求されたアセットを参照しています。
-
-
-## 公開アセットはどのようにパッケージングされる?
-
-
-ビルドプロセス中に `public` フォルダの内容が処理され、アプリケーションのクラスパスに追加されます。
-
-
-アプリケーションをパッケージングすると、サブプロジェクトを含むすべてのアプリケーションのアセットが単一の `target/my-first-app-1.0.0-assets.jar` に集約されます。この jar はディストリビューションに含まれるので、Play アプリケーションはこれらのアセットを提供することができます。この jar はアセットを CDN やリバースプロキシにデプロイすることもできます。
-
-
-## アセットコントローラ
-
-
-Play には、公開アセットを提供する組み込みのコントローラが付属しています。このコントローラはデフォルトでキャッシュ機能、ETag, gzip, そして圧縮をサポートします。
-
-
-このコントローラはデフォルトの Play JAR において `controllers.Assets` として利用可能であり、引数を二つ持つ `at` アクションを定義しています:
-
-```
-Assets.at(path: String, file: String)
-```
-
-
-`path` のパラメータは固定されており、アクションによって管理されるディレクトリを定義する必要があります。 通常、`file` パラメータはリクエストパスから動的に抽出されます。
-
-
-以下は、`conf/routes` ファイルにおける `Assets` コントローラの典型的なマッピングです:
-
-```
-GET /assets/*file controllers.Assets.at(path="/public", file)
-```
-
-
-`*file` を正規表現 `.*` にマッチする動的な部分として定義したことに注目してください。このため、例えば次のようなリクエストをサーバに送信した場合:
-
-```
-GET /assets/javascripts/jquery.js
-```
-
-
-ルータは次のパラメータを使用して `Assets.at` アクションを起動します:
-
-```
-controllers.Assets.at("/public", "javascripts/jquery.js")
-```
-
-
-このアクションは、リクエストされたファイルを探し、そのファイルが存在する場合は提供します。
-
-
-## 公開リソースのリバースルーティング
-
-
-routes ファイルにマッピングされた任意のコントローラと同様に、リバースコントローラが `controllers.routes.Assets` に作成されます。公開リソースを取得するために必要な URL をリバースする際に使用します。テンプレートでの例は以下のようになります:
-
-```html
-
-```
-
-
-以下の結果を生成します。
-
-```html
-
-```
-
-
-ルートをリバースする際は `folder` パラメータを指定しないことに注意してください。これは、`folder` 引数が固定されている `Assets.at` アクションのマッピングをひとつ、ルートファイルに定義しているためです。そのため、指定する必要はありません。
-
-
-しかし、 `Assets.at` アクションにマッピングをふたつ定義している場合、次のようにしてください:
-
-```
-GET /javascripts/*file controllers.Assets.at(path="/public/javascripts", file)
-GET /images/*file controllers.Assets.at(path="/public/images", file)
-```
-
-
-リバースルータを使用する場合は、パラメータを両方指定する必要があります:
-
-```html
-
-
-```
-
-
-## リバースルーティングと公開アセットへのフィンガープリント
-
-
-[sbt-web](https://github.com/sbt/sbt-web) は、例えば以下のビルドファイルのように、高度に設定可能なアセットパイプラインの概念を Play に持ち込みました:
-
-```scala
-pipelineStages := Seq(rjs, digest, gzip)
-```
-
-
-上記の場合、RequireJs オプティマイザ (`sbt-rjs`), ダイジェスト (`sbt-digest`) と、続けて圧縮 (`sbt-gzip`) が順序付けられます。多くの sbt タスクとは異なり、これらのタスクは宣言された順序で、ひとつずつ実行されます。
-
-
-アセットのフィンガープリントにより、ブラウザに対して提供する静的なアセットのキャッシュを積極的に指示することができます。結果として、次にサイトを訪れるユーザはより少ないアセットのダウンロードを要求することになり、ユーザ体験が向上します。Rails も [アセットのフィンガープリント](http://railsguides.jp/asset_pipeline.html#%E3%83%95%E3%82%A3%E3%83%B3%E3%82%AC%E3%83%BC%E3%83%97%E3%83%AA%E3%83%B3%E3%83%88%E3%81%A8%E6%B3%A8%E6%84%8F%E7%82%B9) の利点を述べています。
-
-
-はじめに、上記した `pipelineStages` と、必要なプラグインを `plugins.sbt` に `addSbtPlugin` で宣言します。続いて、バージョン管理するアセットを Play に宣言する必要があります。以下の route ファイルでは、すべてのアセットをバージョン管理するよう宣言しています:
-
-```scala
-GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
-```
-
-
-> `file: Asset` と書くことで `file` がアセットであると示していることを確認してください。
-
-
-それから、例えば `scala.html` ビューでリバースルーターを使います:
-
-```html
-
-```
-
-
-アセットフィンガープリントの利用を強く推奨します。
-
-
-## Etag サポート
-
-
-`Assets` コントローラは、自動的に **ETag** HTTP ヘッダを管理します。ETag の値 (`sbt-digest` がアセットパイプラインで使われている場合) は、ダイジェストまたはリソース名および最終更新日付から生成されます。リソースが JAR ファイルに組み込まれている場合は、その JAR ファイルの最終更新日付が使用されます。
-
-
-Web ブラウザがこの **ETag** を指定してリクエストを行った場合、サーバは **304 NotModified** で応答することができます。
-
-
-## Gzip サポート
-
-
-名前が同じで `gz` 拡張子を持つリソースが見つかった場合、`Assets` コントローラは後者のリソース、そして以下の HTTP ヘッダを提供します:
-
-```
-Content-Encoding: gzip
-```
-
-
-gzip ファイルを生成するには、ビルドに `sbt-gzip` プラグインを取り込み、`pipelineStages` において適切に宣言している必要があります。
-
-
-## `Cache-Control` 命令の追加
-
-
-通常のキャッシュ目的であれば、ETag で十分です。特定のリソース用に独自の `Cache-Control` ヘッダを指定したい場合は、`application.conf` ファイルに指定することができます。例えば:
-
-```
-# Assets configuration
-# ~~~~~
-"assets.cache./public/stylesheets/bootstrap.min.css"="max-age=3600"
-```
-
-
-## 管理アセット
-
-
-Play 2.3 から、管理アセットは [sbt-web](https://github.com/sbt/sbt-web#sbt-web) ベースのプラグインで処理されるようになりました。2.3 より前の Play には、管理アセットの処理として CoffeeScript, LESS, JavaScript Lint (ClosureCompiler) そして RequireJS による最適化がバンドルされていました。以降の節では、sbt-web と 2.2 同等の機能を達成する方法について記述します。とは言え、徐々に sbt-web で多くのプラグインが使えるようになっていくため、Play はこのアセット処理技術に制限されていないことに注意してください。[sbt-web](https://github.com/sbt/sbt-web#sbt-web) プロジェクトを確認して、利用できるより多くのプラグインについて学んでください。
-
-
-多くのプラグインが sbt-web の [js-engine plugin](https://github.com/sbt/sbt-js-engine) を使います。js-engine は、素晴らしい [Trireme](https://github.com/apigee/trireme#trireme) プロジェクトによって JVM 上でも、またはより良いパフォーマンスのために直接 [Node.js](https://nodejs.org/) 上でも Node API で書かれたプラグインを実行することができます。これらのツールは開発サイクルにおいてのみ使用され、Play アプリケーションの実行時には関与しないことに注目してください。Node.js がインストール済みであれば、以下の環境変数を宣言することを推奨します。Unix で `SBT_OPTS` をどこかに定義している場合、以下のように指定することができます:
-
-```bash
-export SBT_OPTS="$SBT_OPTS -Dsbt.jse.engineType=Node"
-```
-
-
-上記の宣言は、あらゆる sbt-web プラグインの実行時に Node.js が使われることを保証します。
diff --git a/manual/detailedTopics/assets/AssetsCoffeeScript.md b/manual/detailedTopics/assets/AssetsCoffeeScript.md
deleted file mode 100644
index ba8f6033..00000000
--- a/manual/detailedTopics/assets/AssetsCoffeeScript.md
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-# CoffeeScript を使う
-
-
-[CoffeeScript](http://coffeescript.org/) は、小さくかつエレガントな言語で、JavaScript へコンパイルされます。CoffeeScript は、JavaScript コードを書くためのより良い構文を提供しています。
-
-
-Play では、コンパイルされるアセットは `app/assets` ディレクトリに定義しなければなりません。このアセットはビルドプロセスによって操作され、CoffeeScript ソースは通常の JavaScript ファイルにコンパイルされます。生成された JavaScript ファイルは標準的なリソースとして、他の管理されないアセットと同じように `public/` フォルダに配布されるので、一度コンパイルされればこれらのリソースの使い方に違いはありません。
-
-
-例えば、 `app/assets/javascripts/main.coffee` という CoffeeScript ソースファイルは `public/javascripts/main.js` にある通常の JavaScript リソースとして利用できるようになります。
-
-
-CoffeeScript ソースファイルは `assets` コマンドの実行時や、開発モードでの動作中にブラウザでページを更新すると自動的にコンパイルされます。あらゆるコンパイルエラーはブラウザに表示されます:
-
-[[images/coffeeError.png]]
-
-
-## ディレクトリ構造
-
-
-以下は、CoffeeScript を使うプロジェクトのレイアウト例です:
-
-```
-app
- └ assets
- └ javascripts
- └ main.coffee
-```
-
-
-以下の構文で、コンパイルされた JavaScript ファイルをテンプレートから使うことができます:
-
-```html
-
@@ -229,11 +229,11 @@ addSbtPlugin("com.typesafe.sbt" % "sbt-coffeescript" % "1.0.0")
Coffeescript options have changed. The new options are:
-* `sourceMaps` When set, generates sourceMap files. Defaults to `true`.
+* `sourceMap` When set, generates sourceMap files. Defaults to `true`.
- `CoffeeScriptKeys.sourceMaps := true`
+ `CoffeeScriptKeys.sourceMap := true`
-* `bare` When set, generates JavaScript without the [top-level function safety wrapper](http://coffeescript.org/#lexical-scope). Defaults to `false`.
+* `bare` When set, generates JavaScript without the [top-level function safety wrapper](https://coffeescript.org/#lexical-scope). Defaults to `false`.
`CoffeeScriptKeys.bare := false`
@@ -354,7 +354,7 @@ mainModule | By default, 'main' is used as the module.
modules | The json array of modules.
optimize | The name of the optimizer, defaults to uglify2.
paths | RequireJS path mappings of module ids to a tuple of the build path and production path. By default all WebJar libraries are made available from a CDN and their mappings can be found here (unless the cdn is set to None).
-preserveLicenseComments | Whether to preserve comments or not. Defaults to false given source maps (see http://requirejs.org/docs/errors.html#sourcemapcomments).
+preserveLicenseComments | Whether to preserve comments or not. Defaults to false given source maps (see https://requirejs.org/docs/errors.html#sourcemapcomments).
webJarCdns | CDNs to be used for locating WebJars. By default "org.webjars" is mapped to "jsdelivr".
webJarModuleIds | A sequence of webjar module ids to be used.
@@ -492,7 +492,7 @@ The WS API has changed slightly, and `WS.client` now returns an instance of `WSC
There are various changes included for Anorm in this new release.
-For improved type safety, type of query parameter must be visible, so that it [can be properly converted](https://github.com/playframework/playframework/blob/master/documentation/manual/scalaGuide/main/sql/ScalaAnorm.md#edge-cases). Now using `Any` as parameter value, explicitly or due to erasure, leads to compilation error `No implicit view available from Any => anorm.ParameterValue`.
+For improved type safety, type of query parameter must be visible, so that it [[can be properly converted|ScalaAnorm#edge-cases]]. Now using `Any` as parameter value, explicitly or due to erasure, leads to compilation error `No implicit view available from Any => anorm.ParameterValue`.
```scala
// Wrong
@@ -580,7 +580,7 @@ The session timeout configuration item, `session.maxAge`, used to be an integer,
## Java JUnit superclasses
-The Java `WithApplication`, `WithServer` and `WithBrowser` JUnit test superclasses have been modified to define an `@Before` annotated method. This means, previously where you had to explicitly start a fake application by defining:
+The Java `WithApplication`, `WithServer` and `WithBrowser` JUnit test superclasses have been modified to define an `@Before` annotated method. This means, previously where you had to explicitly start an application by defining:
```java
@Before
@@ -589,11 +589,11 @@ public void setUp() {
}
```
-Now you don't need to. If you need to provide a custom fake application, you can do so by overriding the `provideFakeApplication` method:
+Now you don't need to. If you need to provide a custom application, you can do so by overriding the `provideFakeApplication` method:
```java
@Override
-protected FakeApplication provideFakeApplication() {
+protected Application provideFakeApplication() {
return Helpers.fakeApplication(Helpers.inMemoryDatabase());
}
```
diff --git a/manual/releases/release23/index.toc b/manual/releases/release23/index.toc
new file mode 100644
index 00000000..867c341b
--- /dev/null
+++ b/manual/releases/release23/index.toc
@@ -0,0 +1,2 @@
+Highlights23:What's new?
+Migration23:Migration Guide
diff --git a/manual/releases/Highlights24.md b/manual/releases/release24/Highlights24.md
similarity index 94%
rename from manual/releases/Highlights24.md
rename to manual/releases/release24/Highlights24.md
index 843a4204..fe4e6b65 100644
--- a/manual/releases/Highlights24.md
+++ b/manual/releases/release24/Highlights24.md
@@ -1,4 +1,4 @@
-
+
# What's new in Play 2.4
This page highlights the new features of Play 2.4. If you want learn about the changes you need to make to migrate to Play 2.4, check out the [[Play 2.4 Migration Guide|Migration24]].
@@ -15,7 +15,7 @@ A long term strategy for Play is to remove Play's dependence on global state. P
* More interesting deployment scenarios are possible, such as multiple Play instances in a single JVM, or embedding a lightweight Play application.
* The application lifecycle becomes easier to follow and reason about.
-Removing Play's global state is however a big task that will require some disruptive changes to the way Play applications are written. The approach we are taking to do this is to do as much as possible in Play 2.4 while maintaining backwards compatibility. For a time, many of Play's APIs will support both methods that rely on require global state and methods that don't rely on global state, allowing you to migrate your application to not depend on global state incrementally, rather than all at once when you uprgade to Play 2.4.
+Removing Play's global state is however a big task that will require some disruptive changes to the way Play applications are written. The approach we are taking to do this is to do as much as possible in Play 2.4 while maintaining backwards compatibility. For a time, many of Play's APIs will support both methods that rely on require global state and methods that don't rely on global state, allowing you to migrate your application to not depend on global state incrementally, rather than all at once when you upgrade to Play 2.4.
The first step to removing global state is to make it such that Play components have their dependencies provided to them, rather than looking them up statically. This means providing out of the box support for dependency injection.
@@ -48,9 +48,9 @@ You can read about these new APIs here:
It is now straightforward to embed a Play application. Play 2.4 provides both APIs to start and stop a Play server, as well as routing DSLs for Java and Scala so that routes can be embedded directly in code.
-In Java, see [[Embedding Play|JavaEmbeddingPlay]] as well as information about the [[Routing DSL|JavaRoutingDsl]].
+In Java, see [[Embedding Play|ScalaEmbeddingPlayAkkaHttp]] as well as information about the [[Routing DSL|JavaRoutingDSL]].
-In Scala, see [[Embedding Play|ScalaEmbeddingPlay]] as well as information about the [[String Interpolating Routing DSL|ScalaSirdRouter]].
+In Scala, see [[Embedding Play|ScalaEmbeddingPlayAkkaHttp]] as well as information about the [[String Interpolating Routing DSL|ScalaSirdRouter]].
## Aggregated reverse routers
@@ -87,7 +87,7 @@ return promise(() -> longComputation())
## Maven/sbt standard layout
-Play will now let you use either its default layout or the directory layout that is the default for Maven and SBT projects. See the [[Anatomy of a Play application|Anatomy]] page for more details.
+Play will now let you use either its default layout or the directory layout that is the default for Maven and sbt projects. See the [[Anatomy of a Play application|Anatomy]] page for more details.
## Anorm
diff --git a/manual/experimental/ReactiveStreamsIntegration.md b/manual/releases/release24/ReactiveStreamsIntegration.md
similarity index 83%
rename from manual/experimental/ReactiveStreamsIntegration.md
rename to manual/releases/release24/ReactiveStreamsIntegration.md
index f7f03e73..a9dbc059 100644
--- a/manual/experimental/ReactiveStreamsIntegration.md
+++ b/manual/releases/release24/ReactiveStreamsIntegration.md
@@ -1,9 +1,9 @@
-
+
# Reactive Streams integration (experimental)
> **Play experimental libraries are not ready for production use**. APIs may change. Features may not work properly.
-[Reactive Streams](http://www.reactive-streams.org/) is a new standard that gives a common API for asynchronous streams. Play 2.4 introduces some wrappers to convert Play's [[Iteratees and Enumerators|Iteratees]] into Reactive Streams objects. This means that Play can integrate with other software that supports Reactive Streams, e.g. [Akka Streams](http://doc.akka.io/docs/akka-stream-and-http-experimental/current/), [RxJava](https://github.com/ReactiveX/RxJavaReactiveStreams) and [others](http://www.reactive-streams.org/announce-1.0.0#implementations).
+[Reactive Streams](http://www.reactive-streams.org/) is a new standard that gives a common API for asynchronous streams. Play 2.4 introduces some wrappers to convert Play's [[Iteratees and Enumerators|Iteratees]] into Reactive Streams objects. This means that Play can integrate with other software that supports Reactive Streams, e.g. [Akka Streams](https://doc.akka.io/docs/akka/2.4.3/scala/stream/index.html), [RxJava](https://github.com/ReactiveX/RxJavaReactiveStreams) and [others](http://www.reactive-streams.org/announce-1.0.0#implementations).
The purpose of the API is:
@@ -31,7 +31,7 @@ Include the Reactive Streams integration library into your project.
libraryDependencies += "com.typesafe.play" %% "play-streams-experimental" % "%PLAY_VERSION%"
```
-All access to the module is through the [`Streams`](api/scala/play/api/libs/streams/Streams$.html) object.
+All access to the module is through the `Streams` object.
Here is an example that adapts a `Future` into a single-element `Publisher`.
@@ -40,12 +40,10 @@ val fut: Future[Int] = Future { ... }
val pubr: Publisher[Int] = Streams.futureToPublisher(fut)
```
-See the `Streams` object's [API documentation](api/scala/play/api/libs/streams/Streams$.html) for more information.
+See the `Streams` object's API documentation for more information.
For more examples you can look at the code used by the experimental [[Akka HTTP server backend|AkkaHttpServer]]. Here are the main files where you can find examples:
-
-
* [ModelConversion](https://github.com/playframework/playframework/blob/2.4.x/framework/src/play-akka-http-server/src/main/scala/play/core/server/akkahttp/ModelConversion.scala)
* [AkkaStreamsConversion](https://github.com/playframework/playframework/blob/2.4.x/framework/src/play-akka-http-server/src/main/scala/play/core/server/akkahttp/AkkaStreamsConversion.scala)
* [AkkaHttpServer](https://github.com/playframework/playframework/blob/2.4.x/framework/src/play-akka-http-server/src/main/scala/play/core/server/akkahttp/AkkaHttpServer.scala)
diff --git a/manual/releases/release24/index.toc b/manual/releases/release24/index.toc
new file mode 100644
index 00000000..c24236b1
--- /dev/null
+++ b/manual/releases/release24/index.toc
@@ -0,0 +1,3 @@
+Highlights24:What's new?
+!migration24:Migration Guides
+ReactiveStreamsIntegration:Reactive Streams integration (experimental)
\ No newline at end of file
diff --git a/manual/releases/migration24/Anorm.md b/manual/releases/release24/migration24/Anorm.md
similarity index 98%
rename from manual/releases/migration24/Anorm.md
rename to manual/releases/release24/migration24/Anorm.md
index 846f6d9a..a876b29c 100644
--- a/manual/releases/migration24/Anorm.md
+++ b/manual/releases/release24/migration24/Anorm.md
@@ -1,4 +1,4 @@
-
+
# Anorm
Anorm has been pulled out of the core of Play into a separately managed project that can have its own lifecycle. To add a dependency on it, use:
@@ -192,4 +192,4 @@ Binary and large data can also be used as parameters:
- **Joda Time**: New conversions for Joda `Instant` or `DateTime`, from `Long`, `Date` or `Timestamp` column.
- Parses text column as `UUID` value: `SQL("SELECT uuid_as_text").as(scalar[UUID].single)`.
-- Passing `None` for a nullable parameter is deprecated, and typesafe `Option.empty[T]` must be use instead.
\ No newline at end of file
+- Passing `None` for a nullable parameter is deprecated, and typesafe `Option.empty[T]` must be use instead.
diff --git a/manual/releases/migration24/GlobalSettings.md b/manual/releases/release24/migration24/GlobalSettings.md
similarity index 94%
rename from manual/releases/migration24/GlobalSettings.md
rename to manual/releases/release24/migration24/GlobalSettings.md
index ef96552f..8fae2e8a 100644
--- a/manual/releases/migration24/GlobalSettings.md
+++ b/manual/releases/release24/migration24/GlobalSettings.md
@@ -1,4 +1,4 @@
-
+
# Removing `GlobalSettings`
If you are keen to use dependency injection, we are recommending that you move out of your `GlobalSettings` implementation class as much code as possible. Ideally, you should be able to refactor your code so that it is possible to eliminate your `GlobalSettings` class altogether.
@@ -9,7 +9,7 @@ Next follows a method-by-method guide for refactoring your code. Because the API
## Scala
-* `GlobalSettings.beforeStart` and `GlobalSettings.onStart`: Anything that needs to happen on start up should now be happening in the constructor of a dependency injected class. A class will perform its initialisation when the dependency injection framework loads it. If you need eager initialisation (because you need to execute some code *before* the application is actually started), [[define an eager binding|ScalaDependencyInjection#Eager-bindings]].
+* `GlobalSettings.beforeStart` and `GlobalSettings.onStart`: Anything that needs to happen on start up should now be happening in the constructor of a dependency injected class. A class will perform its initialization when the dependency injection framework loads it. If you need eager initialization (because you need to execute some code *before* the application is actually started), [[define an eager binding|ScalaDependencyInjection#Eager-bindings]].
* `GlobalSettings.onStop`: Add a dependency to [`ApplicationLifecycle`](api/scala/play/api/inject/ApplicationLifecycle.html) on the class that needs to register a stop hook. Then, move the implementation of your `GlobalSettings.onStop` method inside the `Future` passed to the `ApplicationLifecycle.addStopHook`. Read [[Stopping/cleaning-up|ScalaDependencyInjection#Stopping/cleaning-up]] for more information.
@@ -49,13 +49,13 @@ Also, mind that if your `Global` class is mixing the `WithFilters` trait, you sh
## Java
-* `GlobalSettings.beforeStart` and `GlobalSettings.onStart`: Anything that needs to happen on start up should now be happening in the constructor of a dependency injected class. A class will perform its initialisation when the dependency injection framework loads it. If you need eager initialisation (for example, because you need to execute some code *before* the application is actually started), [[define an eager binding|JavaDependencyInjection#Eager-bindings]].
+* `GlobalSettings.beforeStart` and `GlobalSettings.onStart`: Anything that needs to happen on start up should now be happening in the constructor of a dependency injected class. A class will perform its initialization when the dependency injection framework loads it. If you need eager initialization (for example, because you need to execute some code *before* the application is actually started), [[define an eager binding|JavaDependencyInjection#Eager-bindings]].
* `GlobalSettings.onStop`: Add a dependency to [`ApplicationLifecycle`](api/java/play/inject/ApplicationLifecycle.html) on the class that needs to register a stop hook. Then, move the implementation of your `GlobalSettings.onStop` method inside the `Promise` passed to the `ApplicationLifecycle.addStopHook`. Read [[Stopping/cleaning-up|JavaDependencyInjection#Stopping/cleaning-up]] for more information.
* `GlobalSettings.onError`: Create a class that inherits from [`HttpErrorHandler`](api/java/play/http/HttpErrorHandler.html), and move the implementation of your `GlobalSettings.onError` inside the `HttpErrorHandler.onServerError` method. Read [[Error Handling|JavaErrorHandling]] for more information.
-* `GlobalSettings.onRequest`: Create a class that inherits from [`DefaultHttpRequestHandler`](api/java/play/http/DefaultHttpRequestHandler.html), and move the implementation of your `GlobalSettings.onRequest` method inside the `DefaultHttpRequestHandler.createAction` method. Read [[Request Handlers|JavaHttpRequestHandlers]] for more information.
+* `GlobalSettings.onRequest`: Create a class that inherits from [`DefaultHttpRequestHandler`](api/java/play/http/DefaultHttpRequestHandler.html), and move the implementation of your `GlobalSettings.onRequest` method inside the `DefaultHttpRequestHandler.createAction` method. Read [[Request Handlers|JavaActionCreator]] for more information.
* `GlobalSettings.onRouteRequest`: There is no simple migration for this method when using the Java API. If you need this, you will have to keep your Global class around for a little longer.
@@ -79,4 +79,4 @@ if(statusCode == play.mvc.Http.Status.BAD_REQUEST) {
* `GlobalSettings.onLoadConfig`: Specify all configuration in your config file or create your own ApplicationLoader (see [[GuiceApplicationBuilder.loadConfig|JavaDependencyInjection#Advanced:-Extending-the-GuiceApplicationLoader]]).
-* `GlobalSettings.filters`: Create a class that inherits from [`HttpFilters`](api/java/play/http/HttpFilters.html), and provide an implementation for `HttpFilter.filters`. Read [[Http Filters|JavaHttpFilters]] for more information.
\ No newline at end of file
+* `GlobalSettings.filters`: Create a class that inherits from [`HttpFilters`](api/java/play/http/HttpFilters.html), and provide an implementation for `HttpFilter.filters`. Read [[Http Filters|JavaHttpFilters]] for more information.
diff --git a/manual/releases/migration24/Migration24.md b/manual/releases/release24/migration24/Migration24.md
similarity index 82%
rename from manual/releases/migration24/Migration24.md
rename to manual/releases/release24/migration24/Migration24.md
index e9f4e2fe..cae28fe0 100644
--- a/manual/releases/migration24/Migration24.md
+++ b/manual/releases/release24/migration24/Migration24.md
@@ -1,8 +1,14 @@
-
+
# Play 2.4 Migration Guide
This is a guide for migrating from Play 2.3 to Play 2.4. If you need to migrate from an earlier version of Play then you must first follow the [[Play 2.3 Migration Guide|Migration23]].
+As well as the information contained on this page, there are is more detailed migration information for some topics:
+
+- [[Migrating GlobalSettings|GlobalSettings]]
+- [[Migrating Plugins to Modules|PluginsToModules]]
+- [[Migrating Anorm|Anorm]]
+
## Java 8 support
The support for Java 6 and Java 7 was dropped and Play 2.4 now requires Java 8. This decision was made based on the fact that [Java 7 reached its End-of-Life in April 2015](https://www.java.com/en/download/faq/java_7.xml). Also, Java 8 enables clean APIs and has better support for functional programming style. If you try to use Play 2.4 with Java 6/7, you will get an error like below:
@@ -13,7 +19,7 @@ java.lang.UnsupportedClassVersionError: play/runsupport/classloader/ApplicationC
A [java.lang.UnsupportedClassVersionError](https://docs.oracle.com/javase/8/docs/api/java/lang/UnsupportedClassVersionError.html) means that reading a Java class file with an older version of Java than the class file was compiled with is unsupported.
-> **Note:** Scala 2.10 does not have full support to all Java 8 language features, like static methods on interfaces. If your project has Java code using these new features present in Java 8, upgrade to use Scala 2.11.6+. See [sbt docs](http://www.scala-sbt.org/0.13/docs/Howto-Scala.html) to learn how to set `scalaVersion` to your project.
+> **Note:** Scala 2.10 does not have full support to all Java 8 language features, like static methods on interfaces. If your project has Java code using these new features present in Java 8, upgrade to use Scala 2.11.6+. See [sbt docs](https://www.scala-sbt.org/0.13/docs/Howto-Scala.html) to learn how to set `scalaVersion` to your project.
## Build changes
@@ -24,7 +30,7 @@ The following steps need to be taken to update your sbt build before you can loa
Update the Play version number in `project/plugins.sbt` to upgrade Play:
```scala
-addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "%PLAY_VERSION%")
+addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.4.0") // Set to latest version of Play 2.4
```
### sbt upgrade
@@ -37,12 +43,9 @@ sbt.version=0.13.8
### Specs2 support in a separate module
-If you were previously using Play's specs2 support, you now need to explicitly add a dependency on that to your project. Additionally, specs2 now requires `scalaz-stream` which isn't available on maven central or any other repositories that sbt uses by default, so you need to add the `scalaz-stream` repository as a resolver:
-
+If you were previously using Play's specs2 support, you now need to explicitly add a dependency on that to your project:
```scala
libraryDependencies += specs2 % Test
-
-resolvers += "scalaz-bintray" at "https://dl.bintray.com/scalaz/releases"
```
If you are using a .scala build file, you will need to add the following import `import play.sbt.PlayImport._`
@@ -68,13 +71,13 @@ Eclipse support can be setup with as little as one extra line to import the plug
IntelliJ is now able to import sbt projects natively, so we recommend using that instead. Alternatively, the sbt-idea plugin can be manually installed and used, instructions can be found [here](https://github.com/mpeltonen/sbt-idea).
-### Play SBT plugin API
+### Play sbt plugin API
-All classes in the SBT plugin are now in the package `play.sbt`, this is particularly pertinent if using `.scala` files to configure your build. You will need to import identifiers from `play.sbt.PlayImport` to use play provided configuration elements.
+All classes in the sbt plugin are now in the package `play.sbt`, this is particularly pertinent if using `.scala` files to configure your build. You will need to import identifiers from `play.sbt.PlayImport` to use play provided configuration elements.
#### `playWatchService` renamed
-The SBT setting key `playWatchService` has been renamed to `fileWatchService`.
+The sbt setting key `playWatchService` has been renamed to `fileWatchService`.
Also the corresponding class has changed. To set the FileWatchService to poll every two seconds, use it like this:
```scala
@@ -169,7 +172,7 @@ If you wish to switch to the injected generator, add the following to your build
routesGenerator := InjectedRoutesGenerator
```
-By default Play will automatically handle the wiring of this router for you using Guice, but depending in the DI approach you're taking, you may be able to customise it.
+By default Play will automatically handle the wiring of this router for you using Guice, but depending in the DI approach you're taking, you may be able to customize it.
The injected routes generator also supports the `@` operator on routes, but it has a slightly different meaning (since everything is injected), if you prefix a controller with `@`, instead of that controller being directly injected, a JSR 330 `Provider` for that controller will be injected. This can be used, for example, to eliminate circular dependency issues, or if you want a new action instantiated per request.
@@ -185,13 +188,13 @@ While Play 2.4 won't force you to use the dependency injected versions of compon
| ------- | --------| -------- |
| [`Lang`](api/scala/play/api/i18n/Lang$.html) | [`Langs`](api/scala/play/api/i18n/Langs.html) | |
| [`Messages`](api/scala/play/api/i18n/Messages$.html) | [`MessagesApi`](api/scala/play/api/i18n/MessagesApi.html) | Using one of the `preferred` methods, you can get a [`Messages`](api/scala/play/api/i18n/Messages.html) instance. |
-| [`DB`](api/scala/play/api/db/DB$.html) | [`DBApi`](api/scala/play/api/db/DBApi.html) or better, [`Database`](api/scala/play/api/db/Database.html) | You can get a particular database using the `@NamedDatabase` annotation. |
-| [`Cache`](api/scala/play/api/cache/Cache$.html) | [`CacheApi`](api/scala/play/api/cache/CacheApi.html) or better | You can get a particular cache using the `@NamedCache` annotation. |
-| [`Cached` object](api/scala/play/api/cache/Cached$.html) | [`Cached` instance](api/scala/play/api/cache/Cached.html) | Use an injected instance instead of the companion object. You can use the `@NamedCache` annotation. |
+| `DB` | [`DBApi`](api/scala/play/api/db/DBApi.html) or better, [`Database`](api/scala/play/api/db/Database.html) | You can get a particular database using the `@NamedDatabase` annotation. |
+| `Cache` | [`CacheApi`](api/scala/play/api/cache/CacheApi.html) or better | You can get a particular cache using the `@NamedCache` annotation. |
+| `Cached` object | [`Cached` instance](api/scala/play/api/cache/Cached.html) | Use an injected instance instead of the companion object. You can use the `@NamedCache` annotation. |
| [`Akka`](api/scala/play/api/libs/concurrent/Akka$.html) | N/A | No longer needed, just declare a dependency on `ActorSystem` |
-| [`WS`](api/scala/play/api/libs/ws/WS$.html) | [`WSClient`](api/scala/play/api/libs/ws/WSClient.html) | |
-| [`Crypto`](api/scala/play/api/libs/Crypto$.html) | [`Crypto`](api/scala/play/api/libs/Crypto.html) | |
-| [`GlobalSettings`](api/scala/play/api/GlobalSettings.html) | [`HttpErrorHandler`](api/scala/play/api/http/HttpErrorHandler.html), [`HttpRequestHandler`](api/scala/play/api/http/HttpRequestHandler.html), and [`HttpFilters`](api/scala/play/api/http/HttpFilters.html)| Read the details in the [[GlobalSettings|Migration24#GlobalSettings]] section below. |
+| `WS` | [`WSClient`](api/scala/play/api/libs/ws/WSClient.html) | |
+| `Crypto` | `Crypto` | |
+| `GlobalSettings` | [`HttpErrorHandler`](api/scala/play/api/http/HttpErrorHandler.html), [`HttpRequestHandler`](api/scala/play/api/http/HttpRequestHandler.html), and [`HttpFilters`](api/scala/play/api/http/HttpFilters.html)| Read the details in the [[GlobalSettings|Migration24#GlobalSettings]] section below. |
#### Java
@@ -199,21 +202,21 @@ While Play 2.4 won't force you to use the dependency injected versions of compon
| ------- | --------| -------- |
| [`Lang`](api/java/play/i18n/Lang.html) | [`Langs`](api/java/play/i18n/Langs.html) | Instances of `Lang` objects are still fine to use |
| [`Messages`](api/java/play/i18n/Messages.html) | [`MessagesApi`](api/java/play/i18n/MessagesApi.html) | Using one of the `preferred` methods, you can get a `Messages` instance, and you can then use `at` to get messages for that lang. |
-| [`DB`](api/java/play/db/DB.html) | [`DBApi`](api/java/play/db/DBApi.html) or better, [`Database`](api/java/play/db/Database.html) | You can get a particular database using the [`@NamedDatabase`](api/java/play/db/NamedDatabase.html) annotation. |
+| `DB` | [`DBApi`](api/java/play/db/DBApi.html) or better, [`Database`](api/java/play/db/Database.html) | You can get a particular database using the [`@NamedDatabase`](api/java/play/db/NamedDatabase.html) annotation. |
| [`JPA`](api/java/play/db/jpa/JPA.html) | [`JPAApi`](api/java/play/db/jpa/JPAApi.html) | |
-| [`Cache`](api/java/play/cache/Cache.html) | [`CacheApi`](api/java/play/cache/CacheApi.html) | You can get a particular cache using the [`@NamedCache`](api/java/play/cache/NamedCache.html) annotation. |
+| `Cache` | [`CacheApi`](api/java/play/cache/CacheApi.html) | You can get a particular cache using the [`@NamedCache`](api/java/play/cache/NamedCache.html) annotation. |
| [`Akka`](api/java/play/libs/Akka.html) | N/A | No longer needed, just declare a dependency on `ActorSystem` |
| [`WS`](api/java/play/libs/ws/WS.html) | [`WSClient`](api/java/play/libs/ws/WSClient.html) | |
-| [`Crypto`](api/java/play/libs/Crypto.html) | [`Crypto`](api/java/play/libs/Crypto.html) | The old static methods have been removed, an instance can statically be accessed using `play.Play.application().injector().instanceOf(Crypto.class)` |
-| [`GlobalSettings`](api/java/play/GlobalSettings.html) | [`HttpErrorHandler`](api/java/play/http/HttpErrorHandler.html), [`HttpRequestHandler`](api/java/play/http/HttpRequestHandler.html), and [`HttpFilters`](api/java/play/http/HttpFilters.html)| Read the details in the [[GlobalSettings|Migration24#GlobalSettings]] section below. |
+| `Crypto` | `Crypto` | The old static methods have been removed, an instance can statically be accessed using `play.Play.application().injector().instanceOf(Crypto.class)` |
+| `GlobalSettings` | [`HttpErrorHandler`](api/java/play/http/HttpErrorHandler.html), [`HttpRequestHandler`](api/java/play/http/HttpRequestHandler.html), and [`HttpFilters`](api/java/play/http/HttpFilters.html)| Read the details in the [[GlobalSettings|Migration24#GlobalSettings]] section below. |
### GlobalSettings
-If you are keen to use dependency injection, we are recommending that you move out of your `GlobalSettings` implementation class as much code as possible. Read the [[`GlobalSettings` migration documentation|GlobalSettings]] for the glory details.
+If you are keen to use dependency injection, we are recommending that you move out of your `GlobalSettings` implementation class as much code as possible. Read the [[`GlobalSettings` migration documentation|GlobalSettings]] for the gory details.
## `Plugin` deprecated
-Both Java [`play.Plugin`](api/java/play/Plugin.html) and Scala [`play.api.Plugin`](api/scala/play/api/Plugin.html) types have been deprecated. Read [[migrating Plugin to Module|PluginsToModules]] to update your code to use [`play.api.inject.Module`](api/scala/play/api/inject/Module.html).
+Both Java `play.Plugin` and Scala `play.api.Plugin` types have been deprecated. Read [[migrating Plugin to Module|PluginsToModules]] to update your code to use [`play.api.inject.Module`](api/scala/play/api/inject/Module.html).
## Configuration changes
@@ -264,7 +267,7 @@ akka {
}
```
-In particular, you might want to try the [default Akka settings](http://doc.akka.io/docs/akka/2.3.11/general/configuration.html#listing-of-the-reference-configuration):
+In particular, you might want to try the [default Akka settings](https://doc.akka.io/docs/akka/2.3.11/general/configuration.html#listing-of-the-reference-configuration):
```
akka {
@@ -292,7 +295,7 @@ play.http.requestHandler = "play.http.DefaultHttpRequestHandler"
### Logging
-Logging is now configured solely via [logback configuration files](http://logback.qos.ch/manual/configuration.html).
+Logging is now configured solely via [logback configuration files](https://logback.qos.ch/manual/configuration.html).
## JDBC connection pool
@@ -342,7 +345,7 @@ Additionally, Java actions may now declare a `BodyParser.Of.maxLength` value tha
## JSON API changes
-The semantics of JSON lookups have changed slightly. `JsUndefined` has been removed from the `JsValue` type hierarchy and all lookups of the form `jsv \ foo` or `jsv(bar)` have been moved to [`JsLookup`](api/scala/play/api/libs/json/JsLookup.html). They now return a [`JsLookupResult`](api/scala/play/api/libs/json/JsLookupResult.html) instead of a `JsValue`.
+The semantics of JSON lookups have changed slightly. `JsUndefined` has been removed from the `JsValue` type hierarchy and all lookups of the form `jsv \ foo` or `jsv(bar)` have been moved to `JsLookup`. They now return a `JsLookupResult` instead of a `JsValue`.
If you have code of the form
@@ -356,7 +359,7 @@ the following code is equivalent, if you know the property exists:
val v: JsValue = (json \ "foo" \ "bar").get
```
-If you don't know the property exists, we recommend using pattern matching or the methods on [`JsLookupResult`](api/scala/play/api/libs/json/JsLookupResult.html) to safely handle the `JsUndefined` case, e.g.
+If you don't know the property exists, we recommend using pattern matching or the methods on `JsLookupResult` to safely handle the `JsUndefined` case, e.g.
```scala
val vOpt: Option[JsValue] = (json \ "foo" \ "bar").toOption
@@ -364,7 +367,7 @@ val vOpt: Option[JsValue] = (json \ "foo" \ "bar").toOption
### JsLookup
-All JSON traversal methods have been moved to the [`JsLookup`](api/scala/play/api/libs/json/JsLookup.html) class, which is implicitly applied to all values of type `JsValue` or `JsLookupResult`. In addition to the `apply`, `\`, and `\\` methods, the `head`, `tail`, and `last` methods have been added for JSON arrays. All methods except `\\` return a [`JsLookupResult`](api/scala/play/api/libs/json/JsLookupResult.html), a wrapper for `JsValue` that helps with handling undefined values.
+All JSON traversal methods have been moved to the `JsLookup` class, which is implicitly applied to all values of type `JsValue` or `JsLookupResult`. In addition to the `apply`, `\`, and `\\` methods, the `head`, `tail`, and `last` methods have been added for JSON arrays. All methods except `\\` return a `JsLookupResult`, a wrapper for `JsValue` that helps with handling undefined values.
The methods `as[A]`, `asOpt[A]`, `validate[A]` also exist on `JsLookup`, so code like the below should require no source changes:
@@ -405,23 +408,23 @@ implicit val optionStringReads: Reads[Option[String]] = Reads.optionWithNull[Str
## Testing changes
-[`FakeRequest`](api/java/play/test/FakeRequest.html) has been replaced by [`RequestBuilder`](api/java/play/mvc/Http.RequestBuilder.html).
+`FakeRequest` has been replaced by [`RequestBuilder`](api/java/play/mvc/Http.RequestBuilder.html).
The reverse ref router used in Java tests has been removed. Any call to `Helpers.call` that was passed a ref router can be replaced by a call to `Helpers.route` which takes either a standard reverse router reference or a `RequestBuilder`.
## Java TimeoutExceptions
-If you use the Java API, the [`F.Promise`](api/java/play/libs/F.Promise.html) class now throws unchecked [`F.PromiseTimeoutException`s](api/java/play/libs/F.PromiseTimeoutException.html) instead of Java's checked [`TimeoutException`s](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html). The `TimeoutExceptions`s which were previously used were not properly declared with the `throws` keyword. Rather than changing the API to use the `throws` keyword, which would mean users would have to declare `throws` on their methods, the exception was changed to a new unchecked type instead. See [#1227](https://github.com/playframework/playframework/pull/1227) for more information.
+If you use the Java API, the `F.Promise` class now throws unchecked [`F.PromiseTimeoutException`s](api/java/play/libs/F.PromiseTimeoutException.html) instead of Java's checked [`TimeoutException`s](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html). The `TimeoutExceptions`s which were previously used were not properly declared with the `throws` keyword. Rather than changing the API to use the `throws` keyword, which would mean users would have to declare `throws` on their methods, the exception was changed to a new unchecked type instead. See [#1227](https://github.com/playframework/playframework/pull/1227) for more information.
| Old API | New API | Comments |
| ------- | --------| -------- |
-| [`TimeoutException`](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html) | [`F.PromiseTimeoutException`](api/java/play/libs/F.PromiseTimeoutException.html) | |
+| [`TimeoutException`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html) | [`F.PromiseTimeoutException`](api/java/play/libs/F.PromiseTimeoutException.html) | |
## WS client
`WSRequestHolder` has been renamed to `WSRequest` in [Scala](api/scala/play/api/libs/ws/WSRequest.html) and [Java](api/java/play/libs/ws/WSRequest.html). The previous `WSRequest` class has been removed out as it was only used internally to WS for OAuth functionality.
-WS has upgraded from AsyncHttpClient 1.8.x to 1.9.x, which includes a number of breaking changes if using or configuring that library directly. Please see the [AsyncHttpClient Migration Guide](https://github.com/AsyncHttpClient/async-http-client/blob/master/MIGRATION.md) for more details. The upgrade to AsyncHttpClient 1.9.x enables Server Name Indication (SNI) in HTTPS -- this solves a number of problems with HTTPS based CDNs such as Cloudflare which depend heavily on SNI.
+WS has upgraded from AsyncHttpClient 1.8.x to 1.9.x, which includes a number of breaking changes if using or configuring that library directly. Please see the [AsyncHttpClient Migration Guide](https://github.com/AsyncHttpClient/async-http-client/blob/2.0/MIGRATION.md) for more details. The upgrade to AsyncHttpClient 1.9.x enables Server Name Indication (SNI) in HTTPS -- this solves a number of problems with HTTPS based CDNs such as Cloudflare which depend heavily on SNI.
Configuration settings for WS have changed:
@@ -450,9 +453,9 @@ Due to the recent spate of TLS vulnerabilities, there has been more activity to
## Crypto APIs
-Play 2.4's AES encryption now uses [initialization vectors](http://en.wikipedia.org/wiki/Initialization_vector) to randomize each encryption. The Play encryption format has been changed to add support for initialization vectors.
+Play 2.4's AES encryption now uses [initialization vectors](https://en.wikipedia.org/wiki/Initialization_vector) to randomize each encryption. The Play encryption format has been changed to add support for initialization vectors.
-The full name of the new AES transformation used by Play 2.4 is `AES/CTR/NoPadding`. The old transformation was `AES/ECB/PKCS5Padding`. The [`CTR`](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29) mode is much more secure than the `ECB` mode. As before, you can override Play's encryption transformation by setting the `play.crypto.aes.transformation` configuration option. In Play 2.4, any [transformation supported by your JRE](http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher) can be used, including transformations that use an initialization vector.
+The full name of the new AES transformation used by Play 2.4 is `AES/CTR/NoPadding`. The old transformation was `AES/ECB/PKCS5Padding`. The [`CTR`](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29) mode is much more secure than the `ECB` mode. As before, you can override Play's encryption transformation by setting the `play.crypto.aes.transformation` configuration option. In Play 2.4, any [transformation supported by your JRE](https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher) can be used, including transformations that use an initialization vector.
Play 2.4 uses a new encryption format, but it can read data encrypted by earlier versions of Play. However, earlier versions of Play **will not** be able to read data encrypted by Play 2.4. If your Play 2.4 application needs to produce data in the old format then you may want to copy the algorithm from the [Play 2.3 Crypto code](https://github.com/playframework/playframework/blob/2.3.6/framework/src/play/src/main/scala/play/api/libs/Crypto.scala#L187-L277).
@@ -464,7 +467,7 @@ Old format | _hex(cipher(plaintext))_ | writes | reads | | reads
New format I | "1-" + _base64(cipher(plaintext))_ | | | writes | reads
New format II | "2-" + _base64(iv + cipher(plaintext, iv))_ | | | writes | reads
-Usage of the [Java Crypto API](api/java/play/libs/Crypto.html) remains the same even though the output is different:
+Usage of the Java Crypto API remains the same even though the output is different:
```java
import play.libs.Crypto;
@@ -473,7 +476,7 @@ String enc = Crypto.encryptAES(orig);
String dec = Crypto.decryptAES(enc);
```
-Usage of the [Scala Crypto API](api/scala/play/api/libs/Crypto.html) is also the same:
+Usage of the Scala Crypto API is also the same:
```scala
import play.api.libs.Crypto
@@ -535,7 +538,7 @@ The API should be backward compatible with your code using Play 2.3 so there is
## Distribution
-Previously, Play added all the resources to the the `conf` directory in the distribution, but didn't add the `conf` directory to the classpath. Now Play adds the `conf` directory to the classpath by default.
+Previously, Play added all the resources to the `conf` directory in the distribution, but didn't add the `conf` directory to the classpath. Now Play adds the `conf` directory to the classpath by default.
This can be turned off by setting `PlayKeys.externalizeResources := false`, which will cause no `conf` directory to be created in the distribution, and it will not be on the classpath. The contents of the applications `conf` directory will still be on the classpath by virtue of the fact that it's included in the applications jar file.
@@ -563,7 +566,7 @@ serverLoading in Debian := SystemV
The mysterious `OrderedExecutionContext` had [[been retained|Migration22#Concurrent-F.Promise-execution]] in Play for several versions in order to support legacy applications. It was rarely used and has now been removed. If you still need the `OrderedExecutionContext` for some reason, you can create your own implementation based on the [Play 2.3 source](https://github.com/playframework/playframework/blob/2.3.x/framework/src/play/src/main/scala/play/core/j/OrderedExecutionContext.scala). If you haven't heard of this class, then there's nothing you need to do.
-### SubProject Assets
+### Subproject Assets
Any assets in sub projects are now by default placed into /lib/[subproject] to allow files with the same name in the root project / different subprojects without causing them to interfere with each other.
diff --git a/manual/releases/migration24/PluginsToModules.md b/manual/releases/release24/migration24/PluginsToModules.md
similarity index 77%
rename from manual/releases/migration24/PluginsToModules.md
rename to manual/releases/release24/migration24/PluginsToModules.md
index 2b79e7b9..dd03c28d 100644
--- a/manual/releases/migration24/PluginsToModules.md
+++ b/manual/releases/release24/migration24/PluginsToModules.md
@@ -1,7 +1,9 @@
-
+
# Migrating Plugin to Module
-If you have implemented a Play plugin, please consider migrating your implementation to use [`play.api.inject.Module`](api/scala/play/api/inject/Module.html), instead of the deprecated Java [`play.Plugin`](api/java/play/Plugin.html) or Scala [`play.api.Plugin`](api/scala/play/api/Plugin.html) types.
+> **Note:** The deprecated `play.Plugin` system is removed as of 2.5.x.
+
+If you have implemented a Play plugin, please consider migrating your implementation to use [`play.api.inject.Module`](api/scala/play/api/inject/Module.html), instead of the deprecated Java `play.Plugin` or Scala `play.api.Plugin` types.
The main difference between the old `Plugin` API, and the new one using `Module`, is that with the latter we are going to fully embrace Dependency Injection (DI) - you can read [[here|Highlights24#Dependency-Injection]] to understand why Play became opinionated about DI.
@@ -13,26 +15,25 @@ With the old `Plugin` API, you were required to provide a `play.plugins` file co
Start by creating a class that inherits from `play.api.inject.Module`, and provide an implementation for the `bindings` method. In this method you should wire types to concrete implementation so that components provided by your module can be injected in users' code, or in other modules. Next follows an example.
-In Java
+In Java:
@[module-decl](code24/MyModule.java)
-In Scala
+In Scala:
@[module-decl](code24/MyModule.scala)
-
Note that if a component you are defining requires another component, you should simply add the required component as a constructor's dependency, prepending the constructor with the `@javax.inject.Inject` annotation. The DI framework will then take care of the rest.
-> Note that if a component B requires A, then B will be initialized only after A is initialized.
+> **Note:** if a component B requires A, then B will be initialized only after A is initialized.
Next follows an example of a component named `MyComponentImpl` requiring the `ApplicationLifecycle` component.
-In Java
+In Java:
@[components-decl](code24/MyComponent.java)
-In Scala
+In Scala:
@[components-decl](code24/MyComponent.scala)
@@ -45,8 +46,9 @@ play.modules.enabled += "my.module.MyModule"
```
If you are working on a library that will be used by other projects (including sub projects), add the above line in your `reference.conf` file (if you don't have a `reference.conf` yet, create one and place it under `src/main/resources`). Otherwise, if it's in an end Play project, it should be in `application.conf`.
+If it's and end Play project, you could also create a class called `Module` and put it in the root package (the "app" directory).
-> Note: If you are working on a library, it is highly discouraged to use `play.modules.disabled` to disable modules, as it can lead to undetermistic results when modules are loaded by the application (see [this issue](https://github.com/playframework/play-slick/issues/245) for reasons on why you should not touch `play.modules.disabled`). In fact, `play.modules.disabled` is intended for end users to be able to override what modules are enabled by default.
+> **Note:** If you are working on a library, it is highly discouraged to use `play.modules.disabled` to disable modules, as it can lead to nondeterministic results when modules are loaded by the application (see [this issue](https://github.com/playframework/play-slick/issues/245) for reasons on why you should not touch `play.modules.disabled`). In fact, `play.modules.disabled` is intended for end users to be able to override what modules are enabled by default.
### Compile-time DI
diff --git a/manual/releases/migration24/code24/MyComponent.java b/manual/releases/release24/migration24/code24/MyComponent.java
similarity index 83%
rename from manual/releases/migration24/code24/MyComponent.java
rename to manual/releases/release24/migration24/code24/MyComponent.java
index 0d984014..52fb21fd 100644
--- a/manual/releases/migration24/code24/MyComponent.java
+++ b/manual/releases/release24/migration24/code24/MyComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2015 Typesafe Inc.
+ * Copyright (C) 2009-2019 Lightbend Inc.
*/
//#components-decl
@@ -19,4 +19,4 @@ public MyComponentImpl(ApplicationLifecycle lifecycle) {
});
}
}
-//#components-decl
\ No newline at end of file
+//#components-decl
diff --git a/manual/releases/release24/migration24/code24/MyComponent.scala b/manual/releases/release24/migration24/code24/MyComponent.scala
new file mode 100644
index 00000000..4a29b695
--- /dev/null
+++ b/manual/releases/release24/migration24/code24/MyComponent.scala
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package scaladoc {
+ package mycomponent {
+
+//#components-decl
+ import javax.inject.Inject
+ import play.api.inject.ApplicationLifecycle
+ import scala.concurrent.Future
+
+ trait MyComponent
+
+ class MyComponentImpl @Inject()(lifecycle: ApplicationLifecycle) extends MyComponent {
+ // previous contents of Plugin.onStart
+ lifecycle.addStopHook { () =>
+ // previous contents of Plugin.onStop
+ Future.successful(())
+ }
+ }
+//#components-decl
+ }
+}
diff --git a/manual/releases/migration24/code24/MyModule.java b/manual/releases/release24/migration24/code24/MyModule.java
similarity index 82%
rename from manual/releases/migration24/code24/MyModule.java
rename to manual/releases/release24/migration24/code24/MyModule.java
index ce0c6a16..1f8dbbe2 100644
--- a/manual/releases/migration24/code24/MyModule.java
+++ b/manual/releases/release24/migration24/code24/MyModule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2015 Typesafe Inc.
+ * Copyright (C) 2009-2019 Lightbend Inc.
*/
//#module-decl
@@ -17,4 +17,4 @@ public Seq> bindings(Environment environment, Configuration configura
);
}
}
-//#module-decl
\ No newline at end of file
+//#module-decl
diff --git a/manual/releases/release24/migration24/code24/MyModule.scala b/manual/releases/release24/migration24/code24/MyModule.scala
new file mode 100644
index 00000000..56753e01
--- /dev/null
+++ b/manual/releases/release24/migration24/code24/MyModule.scala
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package scaladoc {
+ package module {
+
+ import mycomponent._
+//#module-decl
+ import play.api.Configuration
+ import play.api.Environment
+ import play.api.inject.Binding
+ import play.api.inject.Module
+
+ class MyModule extends Module {
+ def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = {
+ Seq(
+ bind[MyComponent].to[MyComponentImpl]
+ )
+ }
+ }
+//#module-decl
+
+//#components-decl
+ import play.api.inject.ApplicationLifecycle
+
+ trait MyComponents {
+ def applicationLifecycle: ApplicationLifecycle
+ lazy val component: MyComponent = new MyComponentImpl(applicationLifecycle)
+ }
+//#components-decl
+ }
+}
diff --git a/manual/releases/release24/migration24/index.toc b/manual/releases/release24/migration24/index.toc
new file mode 100644
index 00000000..567118fc
--- /dev/null
+++ b/manual/releases/release24/migration24/index.toc
@@ -0,0 +1,4 @@
+Migration24:Migration Guide
+GlobalSettings:Removing `GlobalSettings`
+Anorm:Migrating Anorm
+PluginsToModules:Migrating Plugin to Module
\ No newline at end of file
diff --git a/manual/releases/release25/Highlights25.md b/manual/releases/release25/Highlights25.md
new file mode 100644
index 00000000..e722db6d
--- /dev/null
+++ b/manual/releases/release25/Highlights25.md
@@ -0,0 +1,93 @@
+
+# What's new in Play 2.5
+
+This page highlights the new features of Play 2.5. If you want to learn about the changes you need to make to migrate to Play 2.5, check out the [[Play 2.5 Migration Guide|Migration25]].
+
+## New streaming API based on Akka Streams
+
+The main theme of Play 2.5 has been moving from Play's iteratee-based asynchronous IO API to [Akka Streams](https://doc.akka.io/docs/akka/2.4.3/scala/stream/stream-introduction.html).
+
+At its heart, any time you communicate over the network, or write/read some data to the filesystem, some streaming is involved. In many cases, this streaming is done at a low level, and the framework exposes the materialized values to your application as in-memory messages. This is the case for many Play actions, a body parser converts the request body stream into an object such as a parsed JSON object, which the application consumes, and the returned result body is a JSON object that Play then turns back into a stream.
+
+Traditionally, on the JVM, streaming is done using the blocking `InputStream` and `OutputStream` APIs. These APIs require a dedicated thread to use them - when reading, that thread must block and wait for data, when writing, that thread must block and wait for the data to be flushed. An asynchronous framework, such as Play, offers many advantages because it limits the resources it requires by not using blocking APIs such as these. Instead, for streaming, an asynchronous API needs to be used, where the framework is notified that there's data to read or that data has been written, rather than having to have a thread block and wait for it.
+
+Prior to Play 2.5, Play used Iteratees as this asynchronous streaming mechanism, but now it uses Akka Streams.
+
+### Why not iteratees?
+
+Iteratees are a functional approach to handling asynchronous streaming. They are incredibly powerful, while also offering an incredibly small API surface area - the Iteratee API consists of one method, `fold`, the rest is just helpers built on top of this method. Iteratees also provide a very high degree of safety, as long as your code compiles, it's very unlikely that you would have any bugs related to the implementation of an iteratee itself, such as concurrency or error handling, most bugs would be in the "business" logic of the iteratee.
+
+While this safety and simplicity is great, the consequence of it was that it has a very steep learning curve. Programming using iteratees requires a shift in thinking from traditional IO handling, and many developers find that the investment required to make this shift is too high for their IO needs. Another disadvantage of iteratees is that they are practically unimplementable in Java, due to their reliance on many high level functional programming features.
+
+### Why Akka Streams
+
+Akka Streams provides a good balance between safety, simplicity and familiarity. Akka Streams intentionally constrains you in what you can do so that you can only do things correctly, but not as much as iteratees do. Conceptually they are much more familiar to most developers, offering both functional and imperative ways of working with them. Akka Streams also has a first class Java API, making it simple to implement any streaming requirements in Java that are needed.
+
+### Where are Akka Streams used?
+
+The places where you will come across Akka Streams in your Play applications include:
+
+* Filters
+* Streaming response bodies
+* Request body parsers
+* WebSockets
+* Streaming WS client responses
+
+### Reactive Streams
+
+[Reactive Streams](http://reactivestreams.org) is a new specification for asynchronous streaming, which is scheduled for inclusion in JDK9 and available as a standalone library for JDK6 and above. In general, it is not an end-user library, rather it is an SPI that streaming libraries can implement in order to integrate with each other. Both Akka Streams and iteratees provide a reactive streams SPI implementation. This means, existing iteratees code can easily be used with Play's new Akka Streams support. It also means any other reactive streams implementations can be used in Play.
+
+### The future of iteratees
+
+Iteratees still have some use cases where they shine. At current, there is no plan to deprecate or remove them from Play, though they may be moved to a standalone library. Since iteratees provide a reactive streams implementation, they will always be usable in Play.
+
+## Better control over WebSocket frames
+
+The Play 2.5 WebSocket API gives you direct control over WebSocket frames. You can now send and receive binary, text, ping, pong and close frames. If you don't want to worry about this level of detail, Play will still automatically convert your JSON or XML data into the right kind of frame.
+
+## New Java APIs
+
+Play 2.5's Java APIs provide feature parity with the Scala APIs. We have introduced several new Java APIs to do this:
+
+* [`HttpRequestHandler`](api/java/play/http/HttpRequestHandler.html), which allows interception of requests as they come in, before they are sent to the router.
+* [`EssentialAction`](api/java/play/mvc/EssentialAction.html), a low level action used in `EssentialFilter` and `HttpRequestHandler`s.
+* [`EssentialFilter`](api/java/play/mvc/EssentialFilter.html)/[`Filter`](api/java/play/mvc/Filter.html) for writing filters in Java.
+* [`BodyParser`](api/java/play/mvc/BodyParser.html), which allows writing custom body parsers in Java.
+
+## Java API updated to use Java 8 classes
+
+When Play 2.0 was released in 2012, Java had little support for Play's style of asynchronous functional programming. There were no lambdas, futures only had a blocking interface and common functional classes didn't exist. Play provided its own classes to fill the gap.
+
+With Play 2.5 that situation has changed. Java 8 now ships with much better support for Play's style of programming. In Play 2.5 the Java APIs have been revamped to use standard Java 8 classes. This means that Play applications will integrate better with other Java libraries and look more like idiomatic Java.
+
+Here are the main changes:
+
+* Use Java functional interfaces (`Runnable`, `Consumer`, `Predicate`, etc). [[(See Migration Guide.)|JavaMigration25#Replaced-functional-types-with-Java-8-functional-types]]
+* Use Java 8's [`Optional`](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html) instead of Play's `F.Option`. [[(See Migration Guide.)|JavaMigration25#Replaced-F.Option-with-Java-8s-Optional]]
+* Use Java 8's [`CompletionStage`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html) instead of Play's `F.Promise`. [[(See Migration Guide.)|JavaMigration25#Replaced-F.Promise-with-Java-8s-CompletionStage]]
+
+## Support for other logging frameworks
+
+Many of our users want to use their own choice of logging framework but this was not possible until Play 2.5. Now Play's fixed dependency on [Logback](https://logback.qos.ch/) has been removed and Play applications can now use any [SLF4J](https://www.slf4j.org/)-compatible logging framework. Logback is included by default, but you can disable it by including a setting in your `build.sbt` file and replace it with your own choice of framework. See Play's [[docs about logging|SettingsLogger#Using-a-Custom-Logging-Framework]] for more information about using other logging frameworks in Play.
+
+Play applications will need to make a small change to their configuration because one Play's Logback classes has moved to a separate package as part of the change. See the [[Migration Guide|Migration25#Change-to-Logback-configuration]] for more details.
+
+## Logging SQL statements
+
+Play now has an easy way to log SQL statements, built on [jdbcdslog](https://github.com/jdbcdslog/jdbcdslog), that works across all JDBC databases, connection pool implementations and persistence frameworks (Anorm, Ebean, JPA, Slick, etc). When you enable logging you will see each SQL statement sent to your database as well as performance information about how long the statement takes to run.
+
+For more information about how to use SQL logging, see the Play [[Java|JavaDatabase#How-to-configure-SQL-log-statement]] and [[Scala|ScalaDatabase#How-to-configure-SQL-log-statement]] database documentation.
+
+## Netty native socket transport
+
+If you run Play server on Linux you can now get a performance boost by using the [native socket feature](https://netty.io/wiki/native-transports.html) that was introduced in Netty 4.0.
+
+You can learn how to use native sockets in Play documentation on [[configuring Netty|SettingsNetty#Configuring-transport-socket]].
+
+## Performance Improvements
+
+Thanks to various performance optimizations, Play 2.5's performance testing framework shows roughly 60K requests per second, an **almost 20% improvement over Play 2.4.x**.
+
+## WS Improvements
+
+Play WS has been upgraded to AsyncHttpClient 2.0, and now includes a request pipeline filter ([[Scala|ScalaWS#Request-Filters]], [[Java|JavaWS#Request-Filters]]) that can be used to log requests in [cURL format](https://curl.haxx.se/docs/manpage.html).
diff --git a/manual/releases/release25/index.toc b/manual/releases/release25/index.toc
new file mode 100644
index 00000000..a72269a4
--- /dev/null
+++ b/manual/releases/release25/index.toc
@@ -0,0 +1,2 @@
+Highlights25:What's new?
+!migration25:Migration Guides
diff --git a/manual/releases/release25/migration25/CryptoMigration25.md b/manual/releases/release25/migration25/CryptoMigration25.md
new file mode 100644
index 00000000..fe5914c4
--- /dev/null
+++ b/manual/releases/release25/migration25/CryptoMigration25.md
@@ -0,0 +1,98 @@
+
+# Crypto Migration Guide
+
+From Play 1.x, Play has come with a Crypto object that provides some cryptographic operations. This used internally by Play. The Crypto object is not mentioned in the documentation, but is mentioned as "cryptographic utilities" in the scaladoc:
+
+"These utilities are intended as a convenience, however it is important to read each methods documentation and understand the concepts behind encryption to use this class properly. Safe encryption is hard, and there is no substitute for an adequate understanding of cryptography. These methods will not be suitable for all encryption needs."
+
+For a variety of reasons, providing cryptographic utilities as a convenience has turned out not to be workable. In 2.5.x, the Play-specific functionality has been broken into `CookieSigner`, `CSRFTokenSigner` and `AESSigner` traits, and the `Crypto` singleton object deprecated.
+
+The remainder of this document will discuss internal functionality behind Crypto, the suitability (and unsuitability) of cryptographic operations, and migration paths for users moving off Crypto functionality.
+
+For more information about cryptography, we recommend reading the [OWASP Cryptographic Storage Cheatsheet](https://www.owasp.org/index.php/Cryptographic_Storage_Cheat_Sheet).
+
+## Message Authentication
+
+Play uses the `Crypto.sign` method to provide message authentication for session cookies. There are several reasons why `Crypto.sign` should not be used outside the purpose of signing cookies: MAC algorithm independence, additional functionality, and potential misuse of HMAC as a password hashing algorithm.
+
+### MAC Algorithm Independence
+
+Play currently uses HMAC-SHA1 for signing and verifying session cookies. An [HMAC](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code) is a cryptographic function that authenticates that data has not been tampered with, using a secret key (the [[application secret|ApplicationSecret]] defined as play.crypto.secret) together with a message digest function (in this case [SHA-1](https://en.wikipedia.org/wiki/SHA-1)). SHA-1 has suffered [some attacks recently](https://sites.google.com/site/itstheshappening/), but it remains secure when used with an HMAC for [message authenticity](https://www.killring.org/how-broken-is-sha-1).
+
+Play needs to have the flexibility be able to move to a different HMAC function [as needed](http://valerieaurora.org/hash.html) and so, should not be part of the public API.
+
+### Potential New Functionality
+
+Play currently signs the session cookie, but does not add any session timeout or expiration date to the session cookie. This means that, given the appropriate opening, an active attacker could swap out one session cookie for another one.
+
+Play may potentially add [session timeout functionality](https://github.com/google/keyczar/blob/master/java/code/src/org/keyczar/TimeoutSigner.java#L109) to Crypto.sign, which again would result in breaking user level functionality if this is marked as public API.
+
+### Misuse as a Password Hash
+
+Please do not use `Crypto.sign` or any kind of HMAC, as they are not designed for password hashing. MACs are designed to be fast and cheap, while password hashing should be slow and expensive. Please look at scrypt, bcrypt, or PBKDF2 -- [jBCrypt](http://www.mindrot.org/projects/jBCrypt/) in particular is well known as a bcrypt implementation in Java.
+
+## Symmetric Encryption
+
+Crypto contains two methods for symmetric encryption, `Crypto.encryptAES` and `Crypto.decryptAES`. These methods are not used internally by Play, but [significant](https://github.com/playframework/playframework/issues/4407) [developer](https://groups.google.com/d/msg/play-framework-dev/Rlrt89Ky_Rk/j6Iq6-snDw8J) [effort](https://groups.google.com/forum/#!topic/play-framework/Pao8MnADAqw) [has](https://ipsec.pl/play-framework/2014/session-variables-encryption-play-framework.html) gone into reviewing these methods. These methods will be deprecated, and may be removed in future versions.
+
+As alluded to in the warning, these methods are not generally "safe" -- there are some common modes of operation that are not secure using these methods. Here follows a brief description of some cryptographic issues using `Crypto.encryptAES`.
+
+Again, `Crypto.encryptAES` is never used directly in Play, so this isn’t a security vulnerability in Play itself.
+
+### Use of Stream Cipher without Authentication
+
+`Crypto.encryptAES` is, by default, using AES-CTR, a mode of AES that provides encryption but does not provide authentication -- this means that an active attacker can swap out the contents of the encrypted text with something else. This property, known as "malleability", means that it’s possible to [recover plaintext](https://news.ycombinator.com/item?id=639761) under certain conditions, and alter the message. There are two constructions that are used to mitigate this: either the encrypted text is signed (known as “Encrypt Then MAC”) or authenticated encryption, such as AES-GCM, can be used.
+
+Play uses `Crypto.encryptAES` to encrypt the contents of a session cookie (which has a MAC applied). Since Play uses "Encrypt Then MAC", it is not vulnerable to attack -- however, users who are making use of symmetric encryption without a MAC are potentially vulnerable.
+
+Users are encouraged not to implement their own Encrypt-Then-MAC construction. Instead, the appropriate solution here is authenticated encryption, which both authenticates and encrypts data at the same time -- see the migration section for details.
+
+### Violation of Key Separation Principle
+
+Although using AES with an HMAC is considered a secure construction, there is a problem in the way that Play uses the secret key for encryption. The "key separation principle" says that you should only ever use one key for one purpose. In this case, not only is play.crypto.secret is used for signing, but also encryption in `Crypto.encryptAES`.
+
+For customers who are using `Crypto.encryptAES`, there is no immediate security vulnerability that results from the mixing of key usage here:
+
+"With HMAC vs AES, no such interference is known. The *general feeling* of cryptographers is that AES and SHA-1 (or SHA-256) are "sufficiently different" that there should be no practical issue with using the same key for AES and HMAC/SHA-1." -- .
+
+Once the application gets larger, the key separation principle might be also violated in another way: If `Crypto.encryptAES` is used for multiple purposes, using separate keys is also advised.
+
+### Global configuration of mode
+
+As mentioned above, AES can be used with various modes of operation. Using a different mode might require different additional security measures.
+
+Play, however, offers configuring mode of operation globally by configuring the play.crypto.aes.transformation configuration option. That is, it influences whole application, including all libraries that use `Crypto.encryptAES`. As a result, it is hard to know exactly what the impact of changing the option on the whole application.
+
+## Migration
+
+There are several migration paths from Crypto functionality. In order of preference, they are Kalium, Keyczar, or pure JCA.
+
+### Kalium
+
+If you have control over binaries in your production environment and do not have external requirements for NIST approved algorithms: use [Kalium](https://abstractj.github.io/kalium/), a wrapper over the [libsodium](https://download.libsodium.org/doc/) library.
+
+If you need a MAC replacement for `Crypto.sign`, use `org.abstractj.kalium.keys.AuthenticationKey`, which implements HMAC-SHA512/256.
+
+If you want a symmetric encryption replacement for `Crypto.encryptAES`, then use `org.abstractj.kalium.crypto.SecretBox`, which implements [secret-key authenticated encryption](https://download.libsodium.org/doc/secret-key_cryptography/authenticated_encryption.html).
+
+Note that Kalium does require that a libsodium binary be [installed](https://download.libsodium.org/doc/installation/index.html), preferably from source that you have verified.
+
+### Keyczar
+
+If you are looking for a pure Java solution or depend on NIST approved algorithms, [Keyczar](https://tersesystems.com/2015/10/05/effective-cryptography-in-the-jvm/) provides a high level cryptographic library on top of JCA. Note that Keyczar does not have the same level of support as libsodium / Kalium, and so Kalium is preferred.
+
+If you need a MAC replacement for `Crypto.sign`, use `org.keyczar.Signer`.
+
+If you need a symmetric encryption replacement for `Crypto.encryptAES`, then use `org.keyczar.Crypter`.
+
+### JCA
+
+Both Kalium and Keyczar use different cryptographic primitives than Crypto. For users who intend to migrate from Crypto functionality without changing the underlying algorithms, the best option is probably to extract the code from the Crypto library to a user level class.
+
+### Further Reading
+
+There are some papers available on cryptographic design that go over some of the issues addressed by crypto APIs and the complexities involved:
+
+* [The Long Journey from Papers to Software: Crypto APIs](https://crypto.junod.info/IACR15_crypto_school_talk.pdf)
+* [What’s Wrong with Crypto API Design](http://spar.isi.jhu.edu/~mgreen/CryptoAPIs.pdf)
+* [Real World Crypto 2015: Error-prone cryptographic designs (djb)](http://bristolcrypto.blogspot.com/2015/01/real-world-crypto-2015-error-prone.html) and [slides](http://cr.yp.to/talks/2015.01.07/slides-djb-20150107-a4.pdf)
diff --git a/manual/releases/release25/migration25/JavaMigration25.md b/manual/releases/release25/migration25/JavaMigration25.md
new file mode 100644
index 00000000..d95babba
--- /dev/null
+++ b/manual/releases/release25/migration25/JavaMigration25.md
@@ -0,0 +1,176 @@
+
+# Java Migration Guide
+
+In order to better fit in to the Java 8 ecosystem, and to allow Play Java users to make more idiomatic use of Java in their applications, Play has switched to using a number of Java 8 types such as `CompletionStage` and `Function`. Play also has new Java APIs for `EssentialAction`, `EssentialFilter`, `Router`, `BodyParser` and `HttpRequestHandler`.
+
+## New Java APIs
+
+There are several API changes to accommodate writing filters and HTTP request handlers in Java, in particular with the `HttpRequestHandler` interface. If you are using Scala for these components you are still free to use the Scala API if you wish.
+
+### Filter API
+
+You will most likely use `EssentialAction` when creating a filter. You can either use the [`Filter`](api/java/play/mvc/Filter.html) API or the lower-level [`EssentialFilter`](api/java/play/mvc/EssentialFilter.html) API that operates on [`EssentialAction`](api/java/play/mvc/EssentialAction.html)s.
+
+### HttpRequestHandler and ActionCreator
+
+The [`HttpRequestHandler`](api/java/play/http/HttpRequestHandler.html) actually existed in Play 2.4, but now it serves a different purpose. The `createAction` and `wrapAction` methods have been moved to a new interface called [`ActionCreator`](api/java/play/http/ActionCreator.html), and are deprecated in `HttpRequestHandler`. These methods are only applied to Java actions, and are used to intercept requests to the controller's method call, but not all requests.
+
+In 2.5, `HttpRequestHandler`'s main purpose is to provide a handler for the request right after it comes in. This is now consistent with what the Scala implementation does, and provides a way for Java users to intercept the handling of all HTTP requests. Normally, the `HttpRequestHandler` will call the router to find an action for the request, so the new API allows you to intercept that request in Java before it goes to the router.
+
+## Using CompletionStage inside an Action
+
+You must supply the HTTP execution context explicitly as an executor when using a Java `CompletionStage` inside an [[Action|JavaActions]], to ensure that the HTTP.Context remains in scope. If you don't supply the HTTP execution context, you'll get "There is no HTTP Context available from here" errors when you call `request()` or other methods that depend on `Http.Context`.
+
+You can supply the [`play.libs.concurrent.HttpExecutionContext`](api/java/play/libs/concurrent/HttpExecutionContext.html) instance through dependency injection:
+
+``` java
+public class Application extends Controller {
+ @Inject HttpExecutionContext ec;
+
+ public CompletionStage index() {
+ someCompletableFuture.supplyAsync(() -> {
+ // do something with request()
+ }, ec.current());
+ }
+}
+```
+
+## Replaced functional types with Java 8 functional types
+
+A big change in Play 2.5 is the change to use standard Java 8 classes where possible. All functional types have been replaced with their Java 8 counterparts, for example `F.Function1` has been replaced with `java.util.function.Function`.
+
+The move to Java 8 types should enable better integration with other Java libraries as well as with built-in functionality in Java 8.
+
+### How to migrate
+
+**Step 1:** Change all code that references Play functional interfaces to reference Java 8 interfaces instead.
+
+You need to change code that explicitly mentions a type like `F.Function1`. For example:
+
+```java
+void myMethod(F.Callback0 block) { ... }
+```
+
+Becomes:
+
+```java
+void myMethod(Runnable block) { ... }
+```
+
+The table below shows all the changes:
+
+| **old interface** | **new interface**
+| --------------------------------------
+| `F.Callback0` | `java.lang.Runnable`
+| `F.Callback` | `java.util.function.Consumer`
+| `F.Callback2` | `java.util.function.BiConsumer`
+| `F.Callback3` | No counterpart in Java 8, consider using `akka.japi.function.Function3`
+| `F.Predicate` | `java.util.function.Predicate`
+| `F.Function0` | `java.util.function.Supplier`
+| `F.Function1` | `java.util.function.Function`
+| `F.Function2` | `java.util.function.BiFunction`
+
+**Step 2:** Fix any errors caused by checked exceptions that are thrown inside your lambdas.
+
+Unlike the Play functional interfaces, the Java 8 functional interfaces don't permit checked exceptions to be thrown. If your lambda expressions throw a checked exception then you'll need to change the code. (If you don't throw checked exceptions then you can leave the code unchanged.)
+
+You may get a lot of compiler errors but it's pretty easy to get your code working again. Let's suppose your Play 2.4 code uses a `F.Callback0` lambda to stop a database:
+
+```java
+onClose(() -> {
+ database.stop(); // <-- can throw an IOException
+})
+```
+
+In Play 2.5 the `onClose` method has been changed to take a `java.lang.Runnable` argument instead of `F.Callback0`. Because `Runnable`s can't throw checked exceptions the code above won't compile in Play 2.5.
+
+To get the code to compile you can change your lambda code to catch the checked exception (`IOException`) and wrap it in an unchecked exception (`RuntimeException`). It's OK for a `Runnable` to throw an unchecked exception so the code will now compile.
+
+```java
+onClose(() -> {
+ try {
+ database.stop(); // <-- can throw an IOException
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+})
+```
+
+If you don't like adding *try-catch* blocks into your code you can use the [Durian](https://github.com/diffplug/durian) library's [`Errors`](https://diffplug.github.io/durian/javadoc/2.0/com/diffplug/common/base/Errors.html) class to handle exceptions for you.
+
+For example, you can get the same behavior as above, where you convert a checked exception into an unchecked exception, with the code below:
+
+```java
+onClose(Errors.rethrow().wrap(database::stop));
+```
+
+Durian provides other behaviors too, such as [logging an exception](https://diffplug.github.io/durian/javadoc/2.0/com/diffplug/common/base/Errors.html#log--) or writing [your own exception handler](https://diffplug.github.io/durian/javadoc/2.0/com/diffplug/common/base/Errors.html#createHandling-java.util.function.Consumer-). If you want to use Durian you can either include it as a [dependency in your project](https://mvnrepository.com/artifact/com.diffplug.durian/durian) or by copy the source from [two](https://github.com/diffplug/durian/blob/master/src/com/diffplug/common/base/Errors.java) [classes](https://github.com/diffplug/durian/blob/master/src/com/diffplug/common/base/Throwing.java) into your project.
+
+## Replaced `F.Promise` with Java 8's `CompletionStage`
+
+APIs that use `F.Promise` now use the standard Java 8 [`CompletionStage`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html) class.
+
+### How to migrate
+
+**Step 1:** Change all code that returns `F.Promise` to return `CompletionStage` instead. To aid with migration, `F.Promise` also implements the `CompletionStage` interface, which means any existing code that returns `Promise` can still be invoked from code that has been migrated to use `CompletionStage`.
+
+**Step 2:** Replace relevant static methods in `F.Promise` with an equivalent method (many of these use the [`play.libs.concurrent.Futures`](api/java/play/libs/concurrent/Futures.html) helpers, or the statics on [`CompletableFuture`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html)):
+
+| `F.Promise` method | alternative |
+| --------------------------------------------|
+| `Promise.wrap` | `scala.compat.java8.FutureConverters.toJava` |
+| `Promise.sequence` | `Futures.sequence` |
+| `Promise.timeout` | `Futures.timeout` |
+| `Promise.pure` | `CompletableFuture.completedFuture` |
+| `Promise.throwing` | Construct `CompletableFuture` and use `completeExceptionally` |
+| `Promise.promise` | `CompletableFuture.supplyAsync` |
+| `Promise.delayed` | `Futures.delayed` |
+
+**Step 3:** Replace existing instance methods with their equivalent on `CompletionStage`:
+
+| `F.Promise` | `CompletionStage` |
+| -----------------------------------------------|
+| `or` | `applyToEither` |
+| `onRedeem` | `thenAcceptAsync` |
+| `map` | `thenApplyAsync` |
+| `transform` | `handleAsync` |
+| `zip` | `thenCombine` (and manually construct a tuple) |
+| `fallbackTo` | `handleAsync` followed by `thenCompose(Function.identity())` |
+| `recover` | `exceptionally` (or `handleAsync` with `HttpExecution#defaultContext()` if you want `Http.Context` captured). |
+| `recoverWith` | same as `recover`, then use `.thenCompose(Function.identity())` |
+| `onFailure` | `whenCompleteAsync` (use `HttpExecution#defaultContext()` if needed) |
+| `flatMap` | `thenComposeAsync` (use `HttpExecution#defaultContext()` if needed) |
+| `filter` | `thenApplyAsync` and implement the filter manually (use `HttpExecution#defaultContext()` if needed) |
+
+These migrations are explained in more detail in the Javadoc for `F.Promise`.
+
+## Replaced `F.Option` with Java 8's `Optional`
+
+The Play Java API has been converted to use the Java 8 [`Optional`](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html) class instead of Play's `F.Option` type. The `F.Option` type has been removed.
+
+### How to migrate
+
+Replace code that uses `F.Option` with `Optional`. The two types are similar, but their API is different, so you will need to update your code. The main difference between the two types is that while `F.Option` inherits `java.util.Collection`, `Optional` doesn't.
+
+Here follows a short table that should ease the migration:
+
+| `F.Option` | `Optional` |
+| ---------- | ---------- |
+| `F.Option.None()` | `Optional.empty()` |
+| `F.Option.Some(v)` | `Optional.ofNullable(v)` |
+| `o.isDefined()` | `o.isPresent()` |
+| `o.isEmpty()` | `!o.isPresent()` |
+| `o.get()` | `o.get()` |
+| `o.getOrElse(f)` | `o.orElseGet(f)` or `o.orElse(v)` |
+| `o.map(f)` | `o.map(f)` |
+
+`Optional` has a lot more combinators, so we highly encourage you to [learn its API](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html) if you are not familiar with it already.
+
+## Thread Local attributes
+
+Thread Local attributes such as `Http.Context`, `Http.Session` etc are no longer passed to a different execution context when used with `CompletionStage` and `*Async` callbacks.
+More information is [here](https://www.playframework.com/documentation/2.5.x/ThreadPools#Java-thread-locals)
+
+## Deprecated static APIs
+
+Several static APIs were deprecated in Play 2.5, in favour of using dependency injected components. Using static global state is bad for testability and modularity, and it is recommended that you move to dependency injection for accessing these APIs. You should refer to the list in the [[Play 2.4 Migration Guide|Migration24#Dependency-Injected-Components]] to find the equivalent dependency injected component for your static API.
diff --git a/manual/releases/release25/migration25/Migration25.md b/manual/releases/release25/migration25/Migration25.md
new file mode 100644
index 00000000..6d488fdf
--- /dev/null
+++ b/manual/releases/release25/migration25/Migration25.md
@@ -0,0 +1,352 @@
+
+# Play 2.5 Migration Guide
+
+This is a guide for migrating from Play 2.4 to Play 2.5. If you need to migrate from an earlier version of Play then you must first follow the [[Play 2.4 Migration Guide|Migration24]].
+
+As well as the information contained on this page, there is more detailed migration information for some topics:
+
+- [[Streams Migration Guide|StreamsMigration25]] – Migrating to Akka Streams, now used in place of iteratees in many Play APIs
+- [[Java Migration Guide|JavaMigration25]] - Migrating Java applications. Play now uses native Java types for functional types and offers several new customizable components in Java.
+
+Lucidchart has also put together an informative blog post on [upgrading from Play 2.3.x to Play 2.5.x](https://www.lucidchart.com/techblog/2017/02/22/upgrading-play-framework-2-3-play-2-5/).
+
+## How to migrate
+
+The following steps need to be taken to update your sbt build before you can load/run a Play project in sbt.
+
+### Play upgrade
+
+Update the Play version number in project/plugins.sbt to upgrade Play:
+
+```scala
+addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.x")
+```
+
+Where the "x" in `2.5.x` is the minor version of Play you want to use, per instance `2.5.0`.
+
+### sbt upgrade to 0.13.11
+
+Although Play 2.5 will still work with sbt 0.13.8, we recommend upgrading to the latest sbt version, 0.13.11. The 0.13.11 release of sbt has a number of [improvements and bug fixes](https://github.com/sbt/sbt/releases/tag/v0.13.11).
+
+Update your `project/build.properties` so that it reads:
+
+```
+sbt.version=0.13.11
+```
+
+### Play Slick upgrade
+
+If your project is using Play Slick, you need to upgrade it:
+
+```scala
+libraryDependencies += "com.typesafe.play" %% "play-slick" % "2.0.0"
+```
+
+Or:
+
+```scala
+libraryDependencies ++= Seq(
+ "com.typesafe.play" %% "play-slick" % "2.0.0",
+ "com.typesafe.play" %% "play-slick-evolutions" % "2.0.0"
+)
+```
+
+### Play Ebean upgrade
+
+If your project is using Play Ebean, you need to upgrade it:
+
+```scala
+addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "3.0.0")
+```
+
+### ScalaTest + Plus upgrade
+
+If your project is using [[ScalaTest + Play|ScalaTestingWithScalaTest]], you need to upgrade it:
+
+```scala
+libraryDependencies ++= Seq(
+ "org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % "test"
+)
+```
+
+## Scala 2.10 support discontinued
+
+Play 2.3 and 2.4 supported both Scala 2.10 and 2.11. Play 2.5 has dropped support for Scala 2.10 and now only supports Scala 2.11. There are a couple of reasons for this:
+
+1. Play 2.5's internal code makes extensive use of the [scala-java8-compat](https://github.com/scala/scala-java8-compat) library, which only supports Scala 2.11. The *scala-java8-compat* has conversions between many Scala and Java 8 types, such as Scala `Future`s and Java `CompletionStage`s. (You might find this library useful for your code too.)
+
+2. The next version of Play will probably add support for Scala 2.12. It's time for Play to move to Scala 2.11 so that the upcoming transition to 2.12 will be easier.
+
+### How to migrate
+
+**Both Scala and Java users** must configure sbt to use Scala 2.11. Even if you have no Scala code in your project, Play itself uses Scala and must be configured to use the right Scala libraries.
+
+To set the Scala version in sbt, simply set the `scalaVersion` key, eg:
+
+```scala
+scalaVersion := "2.11.8"
+```
+
+If you have a single project build, then this setting can just be placed on its own line in `build.sbt`. However, if you have a multi project build, then the scala version setting must be set on each project. Typically, in a multi project build, you will have some common settings shared by every project, this is the best place to put the setting, eg:
+
+```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: _*)
+```
+
+## Change to Logback configuration
+
+As part of the change to remove Play's hardcoded dependency on Logback [[(see Highlights)|Highlights25#Support-for-other-logging-frameworks]], one of the classes used by Logback configuration had to be moved to another package.
+
+### How to migrate
+
+You will need to update your Logback configuration files (`logback*.xml`) and change any references to the old `play.api.Logger$ColoredLevel` to the new `play.api.libs.logback.ColoredLevel` class.
+
+The new configuration after the change will look something like this:
+
+```xml
+
+```
+
+If you use compile time dependency injection, you will need to change your application loader from using `Logger.configure(...)` to the following:
+
+```scala
+LoggerConfigurator(context.environment.classLoader).foreach { _.configure(context.environment) }
+```
+
+You can find more details on how to set up Play with different logging frameworks are in [[Configuring logging|SettingsLogger#Using-a-Custom-Logging-Framework]] section of the documentation.
+
+## Play WS upgrades to AsyncHttpClient 2
+
+Play WS has been upgraded to use [AsyncHttpClient 2](https://github.com/AsyncHttpClient/async-http-client). This is a major upgrade that uses Netty 4.0. Most of the changes in AHC 2.0 are under the hood, but AHC has some significant refactorings which require breaking changes to the WS API:
+
+* `AsyncHttpClientConfig` replaced by [`DefaultAsyncHttpClientConfig`](https://static.javadoc.io/org.asynchttpclient/async-http-client/2.0.0/org/asynchttpclient/DefaultAsyncHttpClientConfig.html).
+* [`allowPoolingConnection`](https://static.javadoc.io/com.ning/async-http-client/1.9.32/com/ning/http/client/AsyncHttpClientConfig.html#allowPoolingConnections) and `allowSslConnectionPool` are combined in AsyncHttpClient into a single `keepAlive` variable. As such, `play.ws.ning.allowPoolingConnection` and `play.ws.ning.allowSslConnectionPool` are not valid and will throw an exception if configured.
+* [`webSocketIdleTimeout`](https://static.javadoc.io/com.ning/async-http-client/1.9.32/com/ning/http/client/AsyncHttpClientConfig.html#webSocketTimeout) has been removed, so is no longer available in `AhcWSClientConfig`.
+* [`ioThreadMultiplier`](https://static.javadoc.io/com.ning/async-http-client/1.9.32/com/ning/http/client/AsyncHttpClientConfig.html#ioThreadMultiplier) has been removed, so is no longer available in `AhcWSClientConfig`.
+* [`FluentCaseInsensitiveStringsMap`](https://static.javadoc.io/com.ning/async-http-client/1.9.32/com/ning/http/client/FluentCaseInsensitiveStringsMap.html) class is removed and replaced by Netty's `HttpHeader` class.
+* [`Realm.AuthScheme.None`](https://static.javadoc.io/com.ning/async-http-client/1.9.32/com/ning/http/client/Realm.AuthScheme.html#NONE) has been removed, so is no longer available in `WSAuthScheme`.
+
+In addition, there are number of small changes:
+
+* In order to reflect the proper AsyncHttpClient library name, package `play.api.libs.ws.ning` was renamed into `play.api.libs.ws.ahc` and `Ning*` classes were renamed into `Ahc*`. In addition, the AHC configuration settings have been changed to `play.ws.ahc` prefix, i.e. `play.ws.ning.maxConnectionsPerHost` is now `play.ws.ahc.maxConnectionsPerHost`.
+* The deprecated interface `play.libs.ws.WSRequestHolder` has been removed.
+* The `play.libs.ws.play.WSRequest` interface now returns `java.util.concurrent.CompletionStage` instead of `F.Promise`.
+* Static methods that rely on `Play.current` or `Play.application` have been deprecated.
+* Play WS would infer a charset from the content type and append a charset to the `Content-Type` header of the request if one was not already set. This caused some confusion and bugs, and so in 2.5.x the `Content-Type` header does not automatically include an inferred charset. If you explicitly set a `Content-Type` header, the setting is honored as is.
+
+## Deprecated `GlobalSettings`
+
+As part of the on going efforts to move away from global state in Play, `GlobalSettings` and the application `Global` object have been deprecated. For more details, see the [[Play 2.4 migration guide|GlobalSettings]] for how to migrate away from using `GlobalSettings`.
+
+## Removed Plugins API
+
+The Plugins API was deprecated in Play 2.4 and has been removed in Play 2.5. The Plugins API has been superseded by Play's dependency injection and module system which provides a cleaner and more flexible way to build reusable components. For details on how to migrate from plugins to dependency injection see the [[Play 2.4 migration guide|PluginsToModules]].
+
+## Routes generated with InjectedRoutesGenerator
+
+Routes are now generated using the dependency injection aware `InjectedRoutesGenerator`, rather than the previous `StaticRoutesGenerator` which assumed controllers were singleton objects.
+
+To revert back to the earlier behavior (if you have "object MyController" in your code, for example), please add the following line to your `build.sbt` file:
+
+```scala
+routesGenerator := StaticRoutesGenerator
+```
+
+If you're using `Build.scala` instead of `build.sbt` you will need to import the `routesGenerator` settings key:
+
+````scala
+import play.sbt.routes.RoutesCompiler.autoImport._
+````
+
+Using static controllers with the static routes generator is not deprecated, but it is recommended that you migrate to using classes with dependency injection.
+
+## Replaced static controllers with dependency injection
+
+`controllers.ExternalAssets` is now a class, and has no static equivalent. `controllers.Assets` and `controllers.Default` are also classes, and while static equivalents exist, it is recommended that you use the class version.
+
+### How to migrate
+
+The recommended solution is to use classes for all your controllers. The `InjectedRoutesGenerator` is now the default, so the controllers in the routes file are assumed to be classes instead of objects.
+
+If you still have static controllers, you can use `StaticRoutesGenerator` (described above) and add the `@` symbol in front of the route in the `routes` file, e.g.
+
+```
+GET /assets/*file @controllers.ExternalAssets.at(path = "/public", file)
+```
+
+## Deprecated play.Play and play.api.Play methods
+
+The following methods have been deprecated in `play.Play`:
+
+* `public static Application application()`
+* `public static Mode mode()`
+* `public static boolean isDev()`
+* `public static boolean isProd()`
+* `public static boolean isTest()`
+
+Likewise, methods in `play.api.Play` that take an implicit `Application` and delegate to Application, such as `def classloader(implicit app: Application)` are now deprecated.
+
+### How to migrate
+
+These methods delegate to either `play.Application` or `play.Environment` -- code that uses them should use dependency injection to inject the relevant class.
+
+You should refer to the list of dependency injected components in the [[Play 2.4 Migration Guide|Migration24#Dependency-Injected-Components]] to migrate built-in Play components.
+
+For example, the following code injects an environment and configuration into a Controller in Scala:
+
+```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)
+ }
+}
+```
+
+### Handling legacy components
+
+Generally the components you use should not need to depend on the entire application, but sometimes you have to deal with legacy components that require one. You can handle this by injecting the application into one of your components:
+
+```scala
+class FooController @Inject() (appProvider: Provider[Application])
+ extends Controller {
+ implicit lazy val app = appProvider.get()
+ def bar = Action {
+ Ok(Foo.bar(app))
+ }
+}
+```
+
+Note that you usually want to use a `Provider[Application]` in this case to avoid circular dependencies.
+
+Even better, you can make your own `*Api` class that turns the static methods into instance methods:
+
+```scala
+class FooApi @Inject() (appProvider: Provider[Application]) {
+ implicit lazy val app = appProvider.get()
+ def bar = Foo.bar(app)
+ def baz = Foo.baz(app)
+}
+```
+
+This allows you to benefit from the testability you get with DI and still use your library that uses global state.
+
+## Content-Type charset changes
+
+Prior to Play 2.5, Play would add a `charset` parameter to certain content types that do not define a charset parameter, specifically [`application/json`](https://www.iana.org/assignments/media-types/application/json) and [`application/x-www-form-urlencoded`](https://www.iana.org/assignments/media-types/application/x-www-form-urlencoded). Now the `Content-Type` is sent without a charset by default. This applies both to sending requests with `WS` and returning responses from Play actions. If you have a non-spec-compliant client or server that requires you to send a charset parameter, you can explicitly set the `Content-Type` header.
+
+## Guice injector and Guice builder changes
+
+By default, Guice can resolve your circular dependency by proxying an interface in the cycle. Since circular dependencies are generally a code smell, and you can also inject Providers to break the cycle, we have chosen to disable this feature on the default Guice injector. Other DI frameworks also are not likely to have this feature, so it can lead to problems when writing Play modules.
+
+Now there are four new methods on the Guice builders (`GuiceInjectorBuilder` and `GuiceApplicationBuilder`) for customizing how Guice injects your classes:
+* `disableCircularProxies`: disables the above-mentioned behaviour of proxying interfaces to resolve circular dependencies. To allow proxying use `disableCircularProxies(false)`.
+* `requireExplicitBindings`: instructs the injector to only inject classes that are explicitly bound in a module. Can be useful in testing for verifying bindings.
+* `requireAtInjectOnConstructors`: requires a constructor annotated with @Inject to instantiate a class.
+* `requireExactBindingAnnotations`: disables the error-prone feature in Guice where it can substitute a binding for @Named Foo when injecting @Named("foo") Foo.
+
+## CSRF changes
+
+In order to make Play's CSRF filter more resilient to browser plugin vulnerabilities and new extensions, the default configuration for the CSRF filter has been made far more conservative. The changes include:
+
+* Instead of blacklisting `POST` requests, now only `GET`, `HEAD` and `OPTIONS` requests are whitelisted, and all other requests require a CSRF check. This means `DELETE` and `PUT` requests are now checked.
+* Instead of blacklisting `application/x-www-form-urlencoded`, `multipart/form-data` and `text/plain` requests, requests of all content types, including no content type, require a CSRF check. One consequence of this is that AJAX requests that use `application/json` now need to include a valid CSRF token in the `Csrf-Token` header.
+* Stateless header-based bypasses, such as the `X-Requested-With`, are disabled by default.
+
+There's a new config option to bypass the new CSRF protection for requests with certain headers. This config option is turned on by default for the Cookie and Authorization headers, so that REST clients, which typically don't use session authentication, will still work without having to send a CSRF token.
+
+However, since the config option allows through *all* requests without those headers, applications that use other authentication schemes (NTLM, TLS client certificates) will be vulnerable to CSRF. These applications should disable the config option so that their authenticated (cookieless) requests are protected by the CSRF filter.
+
+Finally, an additional option has been added to disable the CSRF check for origins trusted by the CORS filter. Please note that the CORS filter must come *before* the CSRF filter in your filter chain for this to work!
+
+Play's old default behaviour can be restored by adding the following configuration to `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"]
+}
+```
+
+### Getting the CSRF token
+
+Previously, a CSRF token could be retrieved from the HTTP request in any action. Now you must have either a CSRF filter or a CSRF action for `CSRF.getToken` to work. If you're not using a filter, you can use the `CSRFAddToken` action in Scala or `AddCSRFToken` Java annotation to ensure a token is in the session.
+
+Also, a minor bug was fixed in this release in which the CSRF token would be empty (throwing an exception in the template helper) if its signature was invalid. Now it will be regenerated on the same request so a token is still available from the template helpers and `CSRF.getToken`.
+
+For more details, please read the CSRF documentation for [[Java|JavaCsrf]] and [[Scala|ScalaCsrf]].
+
+## Crypto Deprecated
+
+From Play 1.x, Play has come with a `Crypto` object that provides some cryptographic operations. This used internally by Play. The `Crypto` object is not mentioned in the documentation, but is mentioned as “cryptographic utilities” in the scaladoc.
+
+For a variety of reasons, providing cryptographic utilities as a convenience has turned out not to be workable. In 2.5.x, the Play-specific functionality has been broken into `CookieSigner`, `CSRFTokenSigner` and `AESSigner` traits, and the `Crypto` singleton object deprecated.
+
+### How to Migrate
+
+Cryptographic migration will depend on your use case, especially if there is unsafe construction of the cryptographic primitives. The short version is to use [Kalium](https://abstractj.github.io/kalium/) if possible, otherwise use [KeyCzar](https://github.com/google/keyczar) or straight [JCA](https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html).
+
+Please see [[Crypto Migration|CryptoMigration25]] for more details.
+
+## Netty 4 upgrade
+
+Netty has been upgraded from 3.10 to 4.0. One consequence of this is the configuration options for configuring Netty channel options have changed. The full list options can be seen [here](https://netty.io/4.0/api/io/netty/channel/ChannelOption.html).
+
+### How to Migrate
+
+Modify any `play.server.netty.option` keys to use the new keys defined in [ChannelOption](https://netty.io/4.0/api/io/netty/channel/ChannelOption.html). A mapping of some of the more popularly used ones is:
+
+| **Old** | **New** |
+| ------------------
+| `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` |
+
+## Changes to `sendFile`, `sendPath` and `sendResource` methods
+
+Java (`play.mvc.StatusHeader`) and Scala (`play.api.mvc.Results.Status`) APIs had the following behavior before:
+
+| API | Method | Default |
+|:------|:-------------------------------------------|:-------------|
+| Scala | `play.api.mvc.Results.Status.sendResource` | `inline` |
+| Scala | `play.api.mvc.Results.Status.sendPath` | `attachment` |
+| Scala | `play.api.mvc.Results.Status.sendFile` | `attachment` |
+| Java | `play.mvc.StatusHeader.sendInputStream` | `none` |
+| Java | `play.mvc.StatusHeader.sendResource` | `inline` |
+| Java | `play.mvc.StatusHeader.sendPath` | `attachment` |
+| Java | `play.mvc.StatusHeader.sendFile` | `inline` |
+
+In other words, they were mixing `inline` and `attachment` modes when delivering files. Now, when delivering files, paths and resources uses `inline` as the default behavior. Of course, you can alternate between these two modes using the parameters present in these methods.
diff --git a/manual/releases/release25/migration25/StreamsMigration25.md b/manual/releases/release25/migration25/StreamsMigration25.md
new file mode 100644
index 00000000..d82534e6
--- /dev/null
+++ b/manual/releases/release25/migration25/StreamsMigration25.md
@@ -0,0 +1,438 @@
+
+# Streams Migration Guide
+
+Play 2.5 has made several major changes to how it streams data and response bodies.
+
+1. Play 2.5 uses **Akka Streams for streaming**. Previous versions of Play used iteratees for streaming as well as several other ad-hoc types of streaming, such as `WebSocket`, `Chunks`, etc.
+
+ There are two main benefits of the change to use Akka Streams. First, Java users can now access the full feature set of Play, e.g. writing body parsers and filters. Second, the streaming library is now more consistent across Play.
+
+2. Play 2.5 uses **`ByteString` to hold packets of bytes**. Previously, Play used byte arrays (`byte[]`/`ArrayByte`) to hold bytes.
+
+ The `ByteString` class is immutable like Java's `String`, so it's safer and easier to use. Like `String` it does have a small performance cost, because it copies its data when it is constructed, but this is balanced by its cheap concatenation and substring operations.
+
+3. Play 2.5 has a new **`HttpEntity` type for response bodies**. Previously response bodies were a plain stream of bytes. HTTP bodies are now a type of `HttpEntity`: `Strict`, `Streamed` or `Chunked`.
+
+ By telling Play what type of entity to use, applications can have more control over how Play sends HTTP responses. It also makes it easier for Play to optimize how it delivers the body.
+
+## Summary of changes
+
+The following parts of the Play API have been updated:
+
+- results (`Result` body, `chunked`/`feed`/`stream` methods)
+- actions (`EssentialAction`)
+- body parsing (`BodyParser`)
+- WebSockets (`WebSocket`)
+- Server-Sent Events (`EventSource`)
+
+The following types have been changed:
+
+| **Purpose** | **Old types** | **New type**
+| -------
+| Holding bytes | `byte[]`/`Array[Byte]` | `ByteString`
+| Producing a stream | `Enumerator`, `WebSocket.Out`, `Chunks.Out`, `EventSource.Out` | `Source`
+| Transforming a stream to another stream | `Enumeratee` | `Flow`
+| Transforming a stream to a single value | `Iteratee` | `Accumulator`
+| Consuming a stream | `Iteratee` | `Sink`
+
+
+## How to migrate (by API)
+
+The following section gives an overview of how to migrate code that uses different parts of the API.
+
+### Migrating chunked results (`chunked`, `Results.Chunked`)
+
+In Play 2.4 you would create chunked results in Scala with an `Enumerator` and in Java with a `Results.Chunked` object. In Play 2.5 these parts of the API are still available, but they have been deprecated.
+
+If you choose to migrate to the new API, you can create a chunked result by calling the `chunked` method on a `StatusHeader` object and providing an Akka Streams `Source` object for the stream of chunks.
+
+More advanced users may prefer to explicitly create an `HttpEntity.Chunked` object and pass it into the `Result` object constructor.
+
+* To learn how to migrate an Enumerator to a Source, see [Migrating Enumerators to Sources](#Migrating-Enumerators-to-Sources).
+
+### Migrating streamed results (`feed`, `stream`) (Scala only)
+
+In Play 2.4 Scala users could stream results by passing an `Enumerator` to the `feed` or `stream` method. (Java users didn't have a way to stream results, apart from chunked results.) The `feed` method streamed the `Enumerator`'s data then closed the connection. The `stream` method, either streamed or chunked the result and possibly closed the connection, depending on the HTTP version of the connection and the presence or absence of the `Content-Length` header.
+
+In Play 2.5, the `stream` method has been removed and the `feed` method has been deprecated. You can choose whether or not to migrate the `feed` method to the new API. If you use the `stream` method your code will need to be changed.
+
+The new API is to create a `Result` object directly and choose an `HttpEntity` to represent its body. For streamed results, you can use the `HttpEntity.Streamed` class. The `Streamed` class takes a `Source` as a body and an optional `Content-Length` header value. The `Source`'s content will be sent to the client. If the entity has a `Content-Length` header then the connection will be left open, otherwise it will be closed to signal the end of the stream.
+
+* To learn how to migrate an Enumerator to a Source, see [Migrating Enumerators to Sources](#Migrating-Enumerators-to-Sources).
+
+### Migrating WebSockets (`WebSocket`)
+
+In Play 2.4, a WebSocket's bidirectional stream was represented in Java with a pair of `WebSocket.In` and `WebSocket.Out` objects and in Scala with a pair of `Enumerator` and `Iteratee` objects. In Play 2.5, both Java and Scala now use an Akka Streams `Flow` to represent the bidirectional stream.
+
+To migrate your WebSockets code in Play 2.5 you have two options.
+
+The first option is to use the old Play API, which has been deprecated and renamed to `LegacyWebSocket`. This is the easiest option. You just need to change your code that refers to `WebSocket` to refer to `LegacyWebSocket` instead. The `LegacyWebSocket` class gives you an easy migration path from Play 2.4 to Play 2.5.
+
+The second option is to change to the new Play API. To do this you'll need to change your WebSocket code to use an Akka Streams `Flow` object.
+
+#### Migrating Scala WebSockets
+
+The Play 2.4 Scala WebSocket API requires an `Enumerator`/`Iteratee` pair that produces `In` objects and consumes `Out` objects. A pair of `FrameFormatter`s handle the job of getting the data out of the `In` and `Out` objects.
+
+```scala
+case class WebSocket[In, Out](f: RequestHeader => Future[Either[Result, (Enumerator[In], Iteratee[Out, Unit]) => Unit]])(implicit val inFormatter: WebSocket.FrameFormatter[In], val outFormatter: WebSocket.FrameFormatter[Out]) extends Handler {
+```
+
+```scala
+trait FrameFormatter[A] {
+ def transform[B](fba: B => A, fab: A => B): FrameFormatter[B]
+}
+```
+
+The Play 2.5 Scala WebSocket API is built around a `Flow` of `Message`s. A [`Message`](api/scala/play/api/http/websocket/Message.html) represents a [WebSocket frame](https://tools.ietf.org/html/rfc6455#section-5). The `MessageFlowTransformer` type handles transforming high-level objects, like JSON, XML and bytes into `Message` frames. A set of built-in implicit `MessageFlowTransformer`s are provided, and you can also write your own.
+
+```scala
+trait WebSocket extends Handler {
+ def apply(request: RequestHeader): Future[Either[Result, Flow[Message, Message, _]]]
+}
+```
+
+```scala
+sealed trait Message
+case class TextMessage(data: String) extends Message
+case class BinaryMessage(data: ByteString) extends Message
+case class CloseMessage(statusCode: Option[Int] = Some(CloseCodes.Regular), reason: String = "") extends Message
+case class PingMessage(data: ByteString) extends Message
+case class PongMessage(data: ByteString) extends Message
+```
+
+```scala
+trait MessageFlowTransformer[+In, -Out] { self =>
+ def transform(flow: Flow[In, Out, _]): Flow[Message, Message, _]
+}
+```
+
+To migrate, you'll need to translate the bidirectional `Enumerator`/`Iteratee` stream into a `Flow`. You may also need to convert your `In`/`Out` objects into `Message`s using a `MessageFlowTransformer`, although this is not necessary for common types like JSON, since some built-in implicit conversions are provided.
+
+* To learn how to migrate an Enumerator to a Source, see [Migrating Enumerators to Sources](#Migrating-Enumerators-to-Sources).
+* To learn how to migrate an Iteratee to a Sink, see [Migrating Iteratees to Sinks and Accumulators](#Migrating-Iteratees-to-Sinks-and-Accumulators).
+
+#### Migrating Java WebSockets
+
+The Play 2.4 Java WebSocket API uses a `WebSocket.In` object to handle incoming messages and a `WebSocket.Out` object to send outgoing messages. The API supported WebSockets transporting text, bytes or JSON frames.
+
+```java
+return WebSocket.whenReady((in, out) -> {
+ out.write("Hello!");
+ out.close();
+});
+```
+
+The new Play 2.5 API is much more powerful. You can now create a `WebSocket` and return arbitrary WebSocket `Message` frames. The bidirectional `Message` streams are represented as a `Flow`.
+
+```java
+public abstract class WebSocket {
+ public abstract CompletionStage>> apply(Http.RequestHeader request);
+}
+```
+
+If you want to convert WebSocket `Message` frames to your own types you can use the `MappedWebSocketAcceptor` class. Several of these classes are provided for you: `Text`, `Binary` and `Json`. For example:
+
+```java
+return WebSocket.Text.accept(requestHeader -> {
+ // return a Flow
+})
+```
+
+You can also create your own `MappedWebSocketAcceptor` by defining how to convert incoming outgoing messages.
+
+### Migrating Comet
+
+To use [Comet](https://en.wikipedia.org/wiki/Comet_(programming)) in Play you need to produce a chunked HTTP response with specially formatted chunks. Play has a `Comet` class to help produce events on the server that can be sent to the browser. In Play 2.4.x, a new Comet instance had to be created and used callbacks for Java, and an Enumeratee was used for Scala. In Play 2.5, there are new APIs added based on Akka Streams.
+
+#### Migrating Java Comet
+
+Create an Akka Streams source for your objects, and convert them into either `String` or `JsonNode` objects. From there, you can use `play.libs.Comet.string` or `play.libs.Comet.json` to convert your objects into a format suitable for `Results.ok().chunked()`. There is additional documentation in [[JavaComet]].
+
+Because the Java Comet helper is based around callbacks, it may be easier to turn the callback based class into a `org.reactivestreams.Publisher` directly and use `Source.fromPublisher` to create a source.
+
+#### Migrating Scala Comet
+
+Create an Akka Streams source for your objects, and convert them into either `String` or `JsValue` objects. From there, you can use `play.api.libs.Comet.string` or `play.api.libs.Comet.json` to convert your objects into a format suitable for `Ok.chunked()`. There is additional documentation in [[ScalaComet]].
+
+### Migrating Server-Sent events (`EventSource`)
+
+To use [Server-Sent Events](https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events) in Play you need to produce a chunked HTTP response with specially formatted chunks. Play has an `EventSource` interface to help produce events on the server that can be sent to the browser. In Play 2.4 Java and Scala each had quite different APIs, but in Play 2.5 they have been changed so they're both based on Akka Streams.
+
+#### Migrating Java Server-Sent events
+
+In Play 2.4's Java API you produce your stream of chunks with `EventSource`, which is a class that extends `Chunks`. You can construct `Event` objects from strings or JSON objects and then send them in the response by calling `EventSource`'s `send` method.
+
+```java
+EventSource eventSource = new EventSource() {
+ @Override
+ public void onConnected() {
+ send(Event.event("hello"));
+ send(Event.event("world"));
+ ...
+ }
+};
+return ok(eventSource);
+```
+
+In Play 2.5 you'll typically create an Akka Streams `Source` for your application objects, use `Source.map` to convert your objects to `Event`s then finally use `EventSource.chunked` to convert the `Event`s into chunked values. The example below shows how this works for sending a stream of strings.
+
+```java
+Source stringSource = ...;
+Source eventSource = myStrings.map(Event::event);
+return ok().chunked(EventSource.chunked(eventSource)).as("text/event-stream");
+```
+
+* To migrate `EventSource.onConnected`, `EventSource.send`, etc to a `Source`, implement `org.reactivestreams.Publisher` on the class and use `Source.fromPublisher` to create a source from the callbacks.
+
+If you still want to use the same API as in Play 2.4 you can use the `LegacyEventSource` class. This class is the same as the Play 2.4 API, but it has been renamed and deprecated. If you want to use the new API, but retain the same feel as the old imperative API, you can try [`GraphStage`](https://doc.akka.io/docs/akka/2.4.3/java/stream/stream-customize.html#custom-processing-with-graphstage).
+
+#### Migrating Scala Server-Sent events
+
+To use Play 2.4's Scala API you provide an `Enumerator` of application objects then use the `EventSource` `Enumeratee` to convert them into `Event`s. Finally you pass the `Event`s to the `chunked` method where they're converted into chunks.
+
+```scala
+val someDataStream: Enumerator[SomeData] = ???
+Ok.chunked(someDataStream &> EventSource())
+```
+
+In Play 2.5 using `EventSource` with `Enumerator`s and `Enumeratee`s has been deprecated. You can still use an `Enumerator` and `Enumeratee`, but it is recommended that you convert your code to use a `Source` and a `Flow` instead. The `Source` produces the stream of objects and `EventSource.flow`'s `Flow` converts them into `Event`s. For example, code above would be rewritten as:
+
+```scala
+val someDataStream: Source[SomeData, Unit] = ???
+Ok.chunked(someDataStream via EventSource.flow).as("text/event-stream")
+```
+
+* To learn how to migrate an Enumerator to a Source, see [Migrating Enumerators to Sources](#Migrating-Enumerators-to-Sources).
+
+### Migrating custom actions (`EssentialAction`) (Scala only)
+
+Most Scala users will use the `Action` class for their actions. The `Action` class is a type of `EssentialAction` that always parses its body fully before running its logic and sending a result. Some users may have written their own custom `EssentialAction`s so that they can do things like incrementally processing the request body.
+
+If you're only using normal `Action`s in your Play 2.4 application then they do not need any migration. However, if you've written an `EssentialAction`, then you'll need to migrate it to the new API in Play 2.5. The behavior of an `EssentialAction` is still the same, but the signature has changed from Play 2.4:
+
+```scala
+trait EssentialAction extends (RequestHeader => Iteratee[Array[Byte], Result])
+```
+
+to a new signature in Play 2.5:
+
+```scala
+trait EssentialAction extends (RequestHeader => Accumulator[ByteString, Result])
+```
+
+To migrate, you'll need to replace your `Iteratee` with an `Accumulator` and your `Array[Byte]` with a `ByteString`.
+
+* To learn how to migrate an Iteratee to an Accumulator, see [Migrating Iteratees to Sinks and Accumulators](#Migrating-Iteratees-to-Sinks-and-Accumulators).
+* To learn how to migrate an `Array[Byte]` to a `ByteString` see [Migrating byte arrays to ByteStrings](#Migrating-byte-arrays-\(byte[]/Array[Byte]\)-to-ByteStrings).
+
+### Migrating custom body parsers (`BodyParser`) (Scala only)
+
+If you're a Scala user who has a custom `BodyParser` in their Play 2.4 application then you'll need to migrate it to the new Play 2.5 API. The `BodyParser` trait signature looks like this in Play 2.4:
+
+```scala
+trait BodyParser[+A] extends (RequestHeader => Iteratee[Array[Byte], Either[Result, A]])
+```
+
+In Play 2.5 it has changed to use Akka Streams types:
+
+```scala
+trait BodyParser[+A] extends (RequestHeader => Accumulator[ByteString, Either[Result, A]])
+```
+
+To migrate, you'll need to replace your `Iteratee` with an `Accumulator` and your `Array[Byte]` with a `ByteString`.
+
+* To learn how to migrate an Iteratee to an Accumulator, see [Migrating Iteratees to Sinks and Accumulators](#Migrating-Iteratees-to-Sinks-and-Accumulators).
+* To learn how to migrate an `Array[Byte]` to a `ByteString` see [Migrating byte arrays to ByteStrings](#Migrating-byte-arrays-\(byte[]/Array[Byte]\)-to-ByteStrings).
+
+### Migrating `Result` bodies (Scala only)
+
+The `Result` object has changed how it represents the result body and the connection close flag. Instead of taking `body: Enumerator[Array[Byte]], connection: Connection`, it now takes `body: HttpEntity`. The `HttpEntity` type contains information about the body and implicit information about how to close the connection.
+
+You can migrate your existing `Enumerator` by using a `Streamed` entity that contains a `Source` and an optional `Content-Length` and `Content-Type` header.
+
+```scala
+val bodyPublisher: Publisher[ByteString] = Streams.enumeratorToPublisher(bodyEnumerator)
+val bodySource: Source[ByteString, _] = Source.fromPublisher(bodyPublisher)
+val entity: HttpEntity = HttpEntity.Streamed(bodySource)
+new Result(headers, entity)
+```
+
+See the section on migrating `Enumerator`s and migrating to `ByteString` for more information on migrating to these types.
+
+* To learn how to migrate an Iteratee to an Accumulator, see [Migrating Iteratees to Sinks and Accumulators](#Migrating-Iteratees-to-Sinks-and-Accumulators).
+* To learn how to migrate an `Array[Byte]` to a `ByteString` see [Migrating byte arrays to ByteStrings](#Migrating-byte-arrays-\(byte[]/Array[Byte]\)-to-ByteStrings).
+
+You may find that you don't need a stream for the `Result` body at all. If that's the case you might want to use a `Strict` entity for the body.
+
+```scala
+new Result(headers, HttpEntity.Strict(bytes))
+```
+
+## How to migrate (by type)
+
+This section explains how to migrate your byte arrays and streams to the new Akka Streams APIs.
+
+Akka Streams is part of the Akka project. Play uses Akka Streams to provide streaming functionality: sending and receiving sequences of bytes and other objects. The Akka project has a lot of good documentation about Akka Streams. Before you start using Akka Streams in Play it is worth looking at the Akka Streams documentation to see what information is available.
+
+* [Documentation for Java](https://doc.akka.io/docs/akka/2.4.3/java/stream/index.html)
+* [Documentation for Scala](https://doc.akka.io/docs/akka/2.4.3/scala/stream/index.html)
+
+The API documentation can be found under the `akka.stream` package in the main Akka API documentation:
+
+* [Akka Javadoc](https://doc.akka.io/japi/akka/2.4.3/)
+* [Akka Scala](https://doc.akka.io/api/akka/2.4.3/)
+
+When you're first getting started with Akka Streams, the *Basics and working with Flows* section of the Akka documentation is worth a look. It will introduce you to the most important parts of the Akka Streams API.
+
+* [Basics for Java](https://doc.akka.io/docs/akka/2.4.3/java/stream/stream-flows-and-basics.html)
+* [Basics for Scala](https://doc.akka.io/docs/akka/2.4.3/scala/stream/stream-flows-and-basics.html)
+
+You don't need to convert your whole application in one go. Parts of your application can keep using iteratees while other parts use Akka Streams. Akka Streams provides a [reactive streams](http://reactive-streams.org) implementation, and Play's iteratees library also provides a reactive streams implementation, consequently, Play's iteratees can easily be wrapped in Akka Streams and vice versa.
+
+### Migrating byte arrays (`byte[]`/`Array[Byte]`) to `ByteString`s
+
+Refer to the [Java](https://doc.akka.io/japi/akka/2.4.3/index.html) and [Scala](https://doc.akka.io/api/akka/2.4.3/akka/util/ByteString.html) API documentation for `ByteString`.
+
+Examples:
+
+Scala:
+
+```scala
+// Get the empty ByteString (this instance is cached)
+ByteString.empty
+// Create a ByteString from a String
+ByteString("hello")
+ByteString.fromString("hello")
+// Create a ByteString from an Array[Byte]
+ByteString(arr)
+ByteString.fromArray(arr)
+```
+
+Java:
+
+```java
+// Get the empty ByteString (this instance is cached)
+ByteString.empty();
+// Create a ByteString from a String
+ByteString.fromString("hello");
+// Create a ByteString from an Array[Byte]
+ByteString.fromArray(arr);
+```
+
+### Migrating `*.Out`s to `Source`s
+
+Play now uses a `Source` to generate events instead of its old `WebSocket.Out`, `Chunks.Out` and `EventSource.Out` classes. These classes were simple to use, but they were inflexible and they didn't implement [back](https://doc.akka.io/docs/akka/2.4.3/java/stream/stream-flows-and-basics.html#back-pressure-explained) [pressure](https://doc.akka.io/docs/akka/2.4.3/scala/stream/stream-flows-and-basics.html#back-pressure-explained) properly.
+
+You can replace your `*.Out` class with any `Source` that produces a stream. There are lots of ways to create `Source`s ([Java](https://doc.akka.io/docs/akka/2.4.3/java/stream/stream-flows-and-basics.html#Defining_sources__sinks_and_flows)/[Scala](https://doc.akka.io/docs/akka/2.4.3/scala/stream/stream-flows-and-basics.html#Defining_sources__sinks_and_flows).
+
+If you want to replace your `*.Out` with a simple object that you can write messages to and then close, without worrying about back pressure, then you can use the `Source.actorRef` method:
+
+Java:
+
+```java
+Source source = Source.actorRef(256, OverflowStrategy.dropNew())
+ .mapMaterializedValue(sourceActor -> {
+ sourceActor.tell(ByteString.fromString("hello"), null);
+ sourceActor.tell(ByteString.fromString("world"), null);
+ sourceActor.tell(new Status.Success(NotUsed.getInstance()), null);
+ return null;
+ });
+```
+
+Scala:
+
+```scala
+val source = Source.actorRef[ByteString](256, OverflowStrategy.dropNew).mapMaterializedValue { sourceActor =>
+ sourceActor ! ByteString("hello")
+ sourceActor ! ByteString("world")
+ sourceActor ! Status.Success(()) // close the source
+}
+```
+
+### Migrating `Enumerator`s to `Source`s
+
+Play uses `Enumerator`s in many places to produce streams of values.
+
+**Step 1:** Use transitional API (if available)
+
+If you use `Results.chunked` or `Results.feed` you can continue to use the existing methods. These methods have been deprecated, so you may want to change your code anyway.
+
+**Step 2:** Convert `Enumerator` to `Source` with an adapter
+
+You can convert your existing `Enumerator` to a `Source` by first converting it to a reactive streams `Publisher` using `Streams.enumeratorToPublisher`, and then you can convert the publisher to a source using [`Source.fromPublisher`](https://doc.akka.io/api/akka/2.4.3/akka/stream/scaladsl/Source$.html#fromPublisher[T]\(Publisher[T]\):Source[T,NotUsed]), for example:
+
+```scala
+val enumerator: Enumerator[T] = ...
+val source = Source.fromPublisher(Streams.enumeratorToPublisher(enumerator))
+```
+
+**Step 3:** (Optional) Rewrite to a `Source`
+
+Here's a list of some common mappings for enumerator factory methods:
+
+| **Iteratees** | **Akka Streams** | **Notes** |
+| --------
+| `Enumerator.apply(a)` | `Source.single(a)` | |
+| `Enumerator.apply(a, b)` | `Source.apply(List(a, b)))` | |
+| `Enumerator.enumerate(seq)` | `Source.apply(seq)` | `seq` must be immutable |
+| `Enumerator.repeat` | `Source.repeat` | The repeated element is not evaluated each time in Akka Streams |
+| `Enumerator.empty` | `Source.empty` | |
+| `Enumerator.unfold` | `Source.unfold` | |
+| `Enumerator.generateM` | `Source.unfoldAsync` | |
+| `Enumerator.fromStream` | `StreamConverters.fromInputStream` | |
+| `Enumerator.fromFile` | `StreamConverters.fromInputStream` | You have to create an `InputStream` for the `java.io.File` |
+
+### Migrating `Iteratee`s to `Sink`s and `Accumulator`s
+
+**Step 1:** Convert using an adapter
+
+You can convert your existing `Iteratee` to a `Sink` by first converting it to a reactive streams `Subscriber` using `Streams.iterateeToSubscriber`, and then you can convert the subscriber to a sink using [`Sink.fromSubscriber`](https://doc.akka.io/api/akka/2.4.3/akka/stream/scaladsl/Sink$.html#fromSubscriber[T]\(Subscriber[T]\):Sink[T,NotUsed]), for example:
+
+```scala
+val iteratee: Iteratee[T, U] = ...
+val (subscriber, resultIteratee) = Streams.iterateeToSubscriber(iteratee)
+val sink = Sink.fromSubscriber(subscriber)
+```
+
+If you need to return an `Accumulator`, you can instead use the `Streams.iterateeToAccumulator` method.
+
+**Step 2:** (Optional) Rewrite to a `Sink`
+
+Here's a list of some common mappings for iteratee factory methods:
+
+| **Iteratees** | **Akka Streams** | **Notes** |
+| --------
+| `Iteratee.fold` | `Sink.fold` | |
+| `Iteratee.head` | `Sink.headOption` | |
+| `Iteratee.getChunks` | `Sink.seq` | |
+| `Iteratee.foreach` | `Sink.foreach` | |
+| `Iteratee.ignore` | `Sink.ignore` | |
+| `Done` | `Sink.cancelled` | The materialized value can be mapped to produce the result, or if using accumulators, `Accumulator.done` can be used instead. |
+
+### Migrating `Enumeratees`s to `Processor`s
+
+**Step 1:** Convert using an adapter
+
+You can convert your existing `Enumeratee` to a `Flow` by first converting it to a reactive streams `Processor` using `Streams.enumerateeToProcessor`, and then you can convert the processor to a flow using [`Flow.fromProcessor`](https://doc.akka.io/api/akka/2.4.3/akka/stream/scaladsl/Flow$.html#fromProcessor[I,O]\(\(\)⇒Processor[I,O]\):Flow[I,O,NotUsed]), for example:
+
+```scala
+val enumeratee: Enumeratee[A, B] = ...
+val flow = Flow.fromProcessor(() => Streams.enumerateeToProcessor(enumeratee))
+```
+
+**Step 2:** (Optional) Rewrite to a `Flow`
+
+Here's a list of some common mappings for enumeratee factory methods:
+
+| **Iteratees** | **Akka Streams** | **Notes** |
+| --------
+| `Enumeratee.map` | `Flow.map` | |
+| `Enumeratee.mapM` | `Flow.mapAsync` | You have to specify the parallelism in Akka Streams, ie how many elements will be mapped in parallel at a time. |
+| `Enumeratee.mapConcat` | `Flow.mapConcat` | |
+| `Enumeratee.filter` | `Flow.filter` | |
+| `Enumeratee.take` | `Flow.take` | |
+| `Enumeratee.takeWhile` | `Flow.takeWhile` | |
+| `Enumeratee.drop` | `Flow.drop` | |
+| `Enumeratee.dropWhile` | `Flow.dropWhile` | |
+| `Enumeratee.collect` | `Flow.collect` | |
diff --git a/manual/releases/release25/migration25/index.toc b/manual/releases/release25/migration25/index.toc
new file mode 100644
index 00000000..6e0ca978
--- /dev/null
+++ b/manual/releases/release25/migration25/index.toc
@@ -0,0 +1,4 @@
+Migration25:Migration Guide
+StreamsMigration25:Streams Migration Guide
+JavaMigration25:Java Migration Guide
+CryptoMigration25:Crypto Migration Guide
diff --git a/manual/releases/release26/Highlights26.md b/manual/releases/release26/Highlights26.md
new file mode 100644
index 00000000..16319437
--- /dev/null
+++ b/manual/releases/release26/Highlights26.md
@@ -0,0 +1,746 @@
+
+# What's new in Play 2.6
+
+This page highlights the new features of Play 2.6. If you want to learn about the changes you need to make when you migrate to Play 2.6, check out the [[Play 2.6 Migration Guide|Migration26]].
+
+## Scala 2.12 support
+
+Play 2.6 is the first release of Play to have been cross built against Scala 2.12 and 2.11. A number of dependencies were updated so that we can have support for both versions.
+
+You can select which version of Scala you would like to use by setting the `scalaVersion` setting in your `build.sbt`.
+
+For Scala 2.12:
+
+```scala
+scalaVersion := "2.12.6"
+```
+
+For Scala 2.11:
+
+```scala
+scalaVersion := "2.11.12"
+```
+
+## PlayService sbt plugin (experimental)
+
+As of Play 2.6.8, Play also offers a `PlayService` plugin. This is a much more minimal Play configuration oriented towards microservices. It uses the standard Maven layout instead of the traditional Play layout, and does not include twirl templates or the sbt-web functionality. For example:
+
+```scala
+lazy val root = (project in file("."))
+ .enablePlugins(PlayService)
+ .enablePlugins(RoutesCompiler) // place routes in src/main/resources, or remove if using SIRD/RoutingDsl
+ .settings(
+ scalaVersion := "2.12.6",
+ libraryDependencies ++= Seq(
+ guice, // remove if not using Play's Guice loader
+ akkaHttpServer, // or use nettyServer for Netty
+ logback // add Play logging support
+ )
+ )
+```
+
+**Note**: this plugin is considered *experimental*, which means the API may change. We expect it to be stable in Play 2.7.0.
+
+## "Global-State-Free" Applications
+
+The biggest under the hood change is that Play no longer relies on global state. You can still access the global application through `play.api.Play.current` / `play.Play.application()` in Play 2.6, but it is deprecated. This sets the stage for Play 3.0, where there is no global state at all.
+
+You can disable access to global application entirely by setting the following configuration value:
+
+```
+play.allowGlobalApplication=false
+```
+
+The above setting will cause an exception on any invocation of `Play.current`.
+
+## Akka HTTP Server Backend
+
+Play now uses the [Akka-HTTP](https://doc.akka.io/docs/akka-http/current/?language=scala) server engine as the default backend. More detail about Play's integration with Akka-HTTP can be found [[on the Akka HTTP Server page|AkkaHttpServer]]. There is an additional page on [[configuring Akka HTTP|SettingsAkkaHttp]].
+
+The Netty backend is still available, and has been upgraded to use Netty 4.1. You can explicitly configure your project to use Netty [[on the NettyServer page|NettyServer]].
+
+## HTTP/2 support (experimental)
+
+Play now has HTTP/2 support on the Akka HTTP server using the `PlayAkkaHttp2Support` module:
+
+```
+lazy val root = (project in file("."))
+ .enablePlugins(PlayJava, PlayAkkaHttp2Support)
+```
+
+This automates most of the process of setting up HTTP/2. However, it does not work with the `run` command by default. See the [[Akka HTTP Server page|AkkaHttpServer]] for more details.
+
+## Request attributes
+
+Requests in Play 2.6 now contain *attributes*. Attributes allow you to store extra information inside request objects. For example, you can write a filter that sets an attribute in the request and then access the attribute value later from within your actions.
+
+Attributes are stored in a `TypedMap` that is attached to each request. `TypedMap`s are immutable maps that store type-safe keys and values. Attributes are indexed by a key and the key's type indicates the type of the attribute.
+
+Java:
+```java
+// Create a TypedKey to store a User object
+class Attrs {
+ public static final TypedKey USER = TypedKey.create("user");
+}
+
+// Get the User object from the request
+User user = req.attrs().get(Attrs.USER);
+// Put a User object into the request
+Request newReq = req.addAttr(Attrs.USER, newUser);
+```
+
+Scala:
+```scala
+// Create a TypedKey to store a User object
+object Attrs {
+ val User: TypedKey[User] = TypedKey.apply[User]("user")
+}
+
+// Get the User object from the request
+val user: User = req.attrs(Attrs.User)
+// Put a User object into the request
+val newReq = req.addAttr(Attrs.User, newUser)
+```
+
+Attributes are stored in a `TypedMap`. You can read more about attributes in the `TypedMap` documentation: [Javadoc](api/java/play/libs/typedmap/TypedMap.html), [Scaladoc](api/scala/play/api/libs/typedmap/TypedMap.html).
+
+Request tags have now been deprecated and you should migrate to use attributes instead. See the [[tags section|Migration26#Request-tags-deprecation]] in the migration docs for more information.
+
+## Route modifier tags
+
+The routes file syntax now allows you to add "modifiers" to each route that provide custom behavior. We have implemented one such tag in the CSRF filter, the "nocsrf" tag. By default, the following route will not have the CSRF filter applied.
+
+```
++ nocsrf # Don't CSRF protect this route
+POST /api/foo/bar ApiController.foobar
+```
+
+You can also create your own modifiers: the `+` symbol can be followed by any number of whitespace-separated tags.
+
+These are made available in the `HandlerDef` request attribute (which also contains other metadata on the handler definition in the routes file):
+
+Java:
+```java
+import java.util.List;
+import play.routing.HandlerDef;
+import play.routing.Router;
+
+HandlerDef handler = req.attrs().get(Router.Attrs.HANDLER_DEF);
+List modifiers = handler.getModifiers();
+```
+
+Scala:
+```scala
+import play.api.routing.{ HandlerDef, Router }
+import play.api.mvc.RequestHeader
+
+val handler = request.attrs(Router.Attrs.HandlerDef)
+val modifiers = handler.modifiers
+```
+
+## Injectable Twirl Templates
+
+Twirl templates can now be created with a constructor annotation using `@this`. The constructor annotation means that Twirl templates can be injected into templates directly and can manage their own dependencies, rather than the controller having to manage dependencies not only for itself, but also for the templates it has to render.
+
+As an example, suppose a template has a dependency on a component `TemplateRenderingComponent`, which is not used by the controller.
+
+First create a file `IndexTemplate.scala.html` using the `@this` syntax for the constructor. Note that the constructor must be placed **before** the `@()` syntax used for the template's parameters for the `apply` method:
+
+```scala
+@this(trc: TemplateRenderingComponent)
+@(item: Item)
+
+@{trc.render(item)}
+```
+
+By default all generated Scala template classes Twirl creates with the `@this` syntax within Play will automatically be annotated with `@javax.inject.Inject()`. If desired you can change this behavior in `build.sbt`:
+
+```scala
+// Add one or more annotation(s):
+TwirlKeys.constructorAnnotations += "@java.lang.Deprecated()"
+
+// Or completely replace the default one with your own annotation(s):
+TwirlKeys.constructorAnnotations := Seq("@com.google.inject.Inject()")
+```
+
+Now define the controller by injecting the template in the constructor:
+
+Java:
+```java
+public class MyController extends Controller {
+
+ private final views.html.indexTemplate template;
+
+ @Inject
+ public MyController(views.html.indexTemplate template) {
+ this.template = template;
+ }
+
+ public Result index() {
+ return ok(template.render());
+ }
+
+}
+```
+
+Scala:
+```scala
+class MyController @Inject()(indexTemplate: views.html.IndexTemplate,
+ cc: ControllerComponents)
+ extends AbstractController(cc) {
+
+ def index = Action { implicit request =>
+ Ok(indexTemplate())
+ }
+}
+```
+
+Once the template is defined with its dependencies, then the controller can have the template injected into the controller, but the controller does not see `TemplateRenderingComponent`.
+
+## Filters Enhancements
+
+Play now comes with a default set of enabled filters, defined through configuration. This provides a "secure by default" experience for new Play applications, and tightens security on existing Play applications.
+
+The following filters are enabled by default:
+
+* `play.filters.csrf.CSRFFilter` prevents CSRF attacks, see [[ScalaCsrf]] / [[JavaCsrf]]
+* `play.filters.headers.SecurityHeadersFilter` prevents XSS and frame origin attacks, see [[SecurityHeaders]]
+* `play.filters.hosts.AllowedHostsFilter` prevents DNS rebinding attacks, see [[AllowedHostsFilter]]
+
+In addition, filters can now be configured through `application.conf`. To append to the defaults list, use the `+=`:
+
+```
+play.filters.enabled+=MyFilter
+```
+
+If you want to specifically disable a filter for testing, you can also do that from configuration:
+
+```
+play.filters.disabled+=MyFilter
+```
+
+Please see [[the Filters page|Filters]] for more details.
+
+> **NOTE**: If you are migrating from an existing project that does not use CSRF form helpers such as `CSRF.formField`, then you may see "403 Forbidden" on PUT and POST requests, from the CSRF filter. To check this behavior, please add `` to your `logback.xml`. Likewise, if you are running a Play application on something other than localhost, you must configure the [[AllowedHostsFilter]] to specifically allow the hostname/ip you are connecting from.
+
+### gzip filter
+
+If you have the gzip filter enabled you can now also control which responses are and aren't gzipped based on their content types via `application.conf` (instead of writing you own `Filters` class):
+
+```
+play.filters.gzip {
+
+ contentType {
+
+ # If non empty, then a response will only be compressed if its content type is in this list.
+ whiteList = [ "text/*", "application/javascript", "application/json" ]
+
+ # The black list is only used if the white list is empty.
+ # Compress all responses except the ones whose content type is in this list.
+ blackList = []
+ }
+}
+```
+
+Please see [[the gzip filter page|GzipEncoding]] for more details.
+
+## JWT Cookies
+
+Play now uses [JSON Web Token](https://tools.ietf.org/html/rfc7519) (JWT) format for session and flash cookies. This allows for a standardized signed cookie data format, cookie expiration (making replay attacks harder) and more flexibility in signing cookies.
+
+Please see [[Scala|ScalaSessionFlash]] or [[Java|JavaSessionFlash]] pages for more details.
+
+## Logging Marker API
+
+ SLF4J Marker support has been added to [`play.Logger`](api/java/play/Logger.html) and [`play.api.Logger`](api/scala/play/api/Logger.html).
+
+In the Java API, it is a straight port of the SLF4J Logger API. This is useful, but you may find an SLF4J wrapper like [Godaddy Logger](https://github.com/godaddy/godaddy-logger) for a richer logging experience.
+
+In the Scala API, markers are added through a MarkerContext trait, which is added as an implicit parameter to the logger methods, i.e.
+
+```scala
+import play.api._
+logger.info("some info message")(MarkerContext(someMarker))
+```
+
+This opens the door for implicit markers to be passed for logging in several statements, which makes adding context to logging much easier without resorting to MDC. For example, using [Logstash Logback Encoder](https://github.com/logstash/logstash-logback-encoder#loggingevent_custom_event) and an [implicit conversion chain](https://docs.scala-lang.org/tutorials/FAQ/chaining-implicits.html), request information can be encoded into logging statements automatically:
+
+@[logging-request-context-trait](../../working/scalaGuide/main/logging/code/ScalaLoggingSpec.scala)
+
+And then used in a controller and carried through `Future` that may use different execution contexts:
+
+@[logging-log-info-with-request-context](../../working/scalaGuide/main/logging/code/ScalaLoggingSpec.scala)
+
+Note that marker contexts are also very useful for "tracer bullet" style logging, where you want to log on a specific request without explicitly changing log levels. For example, you can add a marker only when certain conditions are met:
+
+@[logging-log-trace-with-tracer-controller](../../working/scalaGuide/main/logging/code/ScalaLoggingSpec.scala)
+
+And then trigger logging with the following TurboFilter in `logback.xml`:
+
+```xml
+
+ TRACER_FILTER
+ TRACER
+ ACCEPT
+
+```
+
+For more information, please see [[ScalaLogging|ScalaLogging#Using-Markers-and-Marker-Contexts]] or [[JavaLogging|JavaLogging#Using-Markers]].
+
+For more information about using Markers in logging, see [TurboFilters](https://logback.qos.ch/manual/filters.html#TurboFilter) and [marker based triggering](https://logback.qos.ch/manual/appenders.html#OnMarkerEvaluator) sections in the Logback manual.
+
+## Configuration improvements
+
+In the Java API, we have moved to the standard `Config` object from Lightbend's Config library instead of `play.Configuration`. This brings the behavior in line with standard config behavior, as the methods now expect all keys to exist. See [[the Java config migration guide|JavaConfigMigration26]] for migration details.
+
+In the Scala API, we have introduced new methods to the `play.api.Configuration` class to simplify the API and allow loading of custom types. You can now use an implicit `ConfigLoader` to load any custom type you want. Like the `Config` API, the new `Configuration#get[T]` expects the key to exist by default and returns a value of type `T`, but there is also a `ConfigLoader[Option[T]]` that allows `null` config values. See the [[Scala configuration docs|ScalaConfig]] for more details.
+
+## Security Logging
+
+A security marker has been added for security related operations in Play, and failed security checks now log at WARN level, with the security marker set. This ensures that developers always know why a particular request is failing, which is important now that security filters are enabled by default in Play.
+
+The security marker also allows security failures to be triggered or filtered distinct from normal logging. For example, to disable all logging with the SECURITY marker set, add the following lines to the `logback.xml` file:
+
+```xml
+
+ SECURITY
+ DENY
+
+```
+
+In addition, log events using the security marker can also trigger a message to a Security Information & Event Management (SIEM) engine for further processing.
+
+## Configuring a Custom Logging Framework in Java
+
+Before, if you want to [[use a custom logging framework|SettingsLogger#Using-a-Custom-Logging-Framework]], you had to configure it using Scala, even if the you have a Java project. Now it is possible to create custom `LoggerConfigurator` in both Java and Scala. To create a `LoggerConfigurator` in Java, you need to implement the given interface, for example, to configure Log4J:
+
+```java
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigFactory;
+import org.slf4j.ILoggerFactory;
+import play.Environment;
+import play.LoggerConfigurator;
+import play.Mode;
+import play.api.PlayException;
+
+import java.io.File;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.*;
+import org.apache.logging.log4j.core.config.Configurator;
+
+public class JavaLog4JLoggerConfigurator implements LoggerConfigurator {
+
+ private ILoggerFactory factory;
+
+ @Override
+ public void init(File rootPath, Mode mode) {
+ Map properties = new HashMap<>();
+ properties.put("application.home", rootPath.getAbsolutePath());
+
+ String resourceName = "log4j2.xml";
+ URL resourceUrl = this.getClass().getClassLoader().getResource(resourceName);
+ configure(properties, Optional.ofNullable(resourceUrl));
+ }
+
+ @Override
+ public void configure(Environment env) {
+ Map properties = LoggerConfigurator.generateProperties(env, ConfigFactory.empty(), Collections.emptyMap());
+ URL resourceUrl = env.resource("log4j2.xml");
+ configure(properties, Optional.ofNullable(resourceUrl));
+ }
+
+ @Override
+ public void configure(Environment env, Config configuration, Map optionalProperties) {
+ // LoggerConfigurator.generateProperties enables play.logger.includeConfigProperties=true
+ Map properties = LoggerConfigurator.generateProperties(env, configuration, optionalProperties);
+ URL resourceUrl = env.resource("log4j2.xml");
+ configure(properties, Optional.ofNullable(resourceUrl));
+ }
+
+ @Override
+ public void configure(Map properties, Optional config) {
+ try {
+ LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
+ loggerContext.setConfigLocation(config.get().toURI());
+
+ factory = org.slf4j.impl.StaticLoggerBinder.getSingleton().getLoggerFactory();
+ } catch (URISyntaxException ex) {
+ throw new PlayException(
+ "log4j2.xml resource was not found",
+ "Could not parse the location for log4j2.xml resource",
+ ex
+ );
+ }
+ }
+
+ @Override
+ public ILoggerFactory loggerFactory() {
+ return factory;
+ }
+
+ @Override
+ public void shutdown() {
+ LoggerContext loggerContext = (LoggerContext) LogManager.getContext();
+ Configurator.shutdown(loggerContext);
+ }
+}
+```
+
+> **Note**: this implementation is fully compatible with Scala version `LoggerConfigurator` and can even be used in Scala projects if necessary, which means that module creators can provide a Java or Scala implementation of LoggerConfigurator and they will be usable in both Java and Scala projects.
+
+## Separate Java Forms module and PlayMinimalJava plugin
+
+The [[Java forms|JavaForms]] functionality has been split out into a separate module. The forms functionality depends on a few Spring modules and the Hibernate validator, so if you are not using forms, you may wish to remove the Java forms module to avoid those unnecessary dependencies.
+
+This module is automatically included by the `PlayJava` plugin, but can be disabled by using the `PlayMinimalJava` plugin instead:
+
+```
+lazy val root = (project in file("."))
+ .enablePlugins(PlayMinimalJava)
+```
+
+## Java Compile Time Components
+
+Just as in Scala, Play now has components to enable [[Java Compile Time Dependency Injection|JavaCompileTimeDependencyInjection]]. The components were created as interfaces that you should `implements` and they provide default implementations. There are components for all the types that could be injected when using [[Runtime Dependency Injection|JavaDependencyInjection]]. To create an application using Compile Time Dependency Injection, you just need to provide an implementation of `play.ApplicationLoader` that uses a custom implementation of `play.BuiltInComponents`, for example:
+
+```java
+import play.routing.Router;
+import play.ApplicationLoader;
+import play.BuiltInComponentsFromContext;
+import play.filters.components.HttpFiltersComponents;
+
+public class MyComponents extends BuiltInComponentsFromContext
+ implements HttpFiltersComponents {
+
+ public MyComponents(ApplicationLoader.Context context) {
+ super(context);
+ }
+
+ @Override
+ public Router router() {
+ return Router.empty();
+ }
+}
+```
+
+The `play.ApplicationLoader`:
+
+```java
+import play.ApplicationLoader;
+
+public class MyApplicationLoader implements ApplicationLoader {
+
+ @Override
+ public Application load(Context context) {
+ return new MyComponents(context).application();
+ }
+
+}
+```
+
+And configure `MyApplicationLoader` as explained in [[Java Compile-Time Dependency Injection docs|JavaCompileTimeDependencyInjection#Application-entry-point]].
+
+## Improved Form Handling I18N support
+
+The `MessagesApi` and `Lang` classes are used for internationalization in Play, and are required to display error messages in forms.
+
+In the past, putting together a form in Play has required [multiple steps](https://www.theguardian.com/info/developer-blog/2015/dec/30/how-to-add-a-form-to-a-play-application), and the creation of a `Messages` instance from a request was not discussed in the context of form handling.
+
+In addition, it was inconvenient to have a `Messages` instance passed through all template fragments when form handling was required, and `Messages` implicit support was provided directly through the controller trait. The I18N API has been refined with the addition of a `MessagesProvider` trait, implicits that are tied directly to requests, and the forms documentation has been improved.
+
+The [`MessagesActionBuilder`](api/scala/play/api/mvc/MessagesActionBuilder.html) has been added. This action builder provides a [`MessagesRequest`](api/scala/play/api/mvc/MessagesRequest.html), which is a [`WrappedRequest`](api/scala/play/api/mvc/WrappedRequest.html) that extends [`MessagesProvider`](api/scala/play/api/i18n/MessagesProvider.html), only a single implicit parameter needs to be made available to templates, and you don't need to extend `Controller` with `I18nSupport`. This is also useful because to use [[CSRF|ScalaCsrf]] with forms, both a `Request` (technically a `RequestHeader`) and a `Messages` object must be available to the template.
+
+```scala
+class FormController @Inject()(messagesAction: MessagesActionBuilder, components: ControllerComponents)
+ extends AbstractController(components) {
+
+ import play.api.data.Form
+ import play.api.data.Forms._
+
+ val userForm = Form(
+ mapping(
+ "name" -> text,
+ "age" -> number
+ )(UserData.apply)(UserData.unapply)
+ )
+
+ def index = messagesAction { implicit request: MessagesRequest[AnyContent] =>
+ Ok(views.html.displayForm(userForm))
+ }
+
+ def post = ...
+}
+```
+
+where `displayForm.scala.html` is defined as:
+
+```twirl
+@(userForm: Form[UserData])(implicit request: MessagesRequestHeader)
+
+@import helper._
+
+@helper.form(action = routes.FormController.post()) {
+ @CSRF.formField @* <- takes a RequestHeader *@
+ @helper.inputText(userForm("name")) @* <- takes a MessagesProvider *@
+ @helper.inputText(userForm("age")) @* <- takes a MessagesProvider *@
+}
+```
+
+For more information, please see [[ScalaI18N]].
+
+### Testing Support
+
+Support for creating `MessagesApi` instances has been improved. Now, when you want to create a [`MessagesApi`](api/scala/play/api/i18n/MessagesApi.html) instance, you can create [`DefaultMessagesApi()`](api/scala/play/api/i18n/DefaultMessagesApi.html) or [`DefaultLangs()`](api/scala/play/api/i18n/DefaultLangs.html) with default arguments. If you want to specify test messages from configuration or from another source, you can pass in those values:
+
+```scala
+val messagesApi: MessagesApi = {
+ val env = new Environment(new File("."), this.getClass.getClassLoader, Mode.Dev)
+ val config = Configuration.reference ++ Configuration.from(Map("play.i18n.langs" -> Seq("en", "fr", "fr-CH")))
+ val langs = new DefaultLangsProvider(config).get
+ new DefaultMessagesApi(testMessages, langs)
+ }
+```
+
+## Future Timeout and Delayed Support
+
+Play's support for futures in asynchronous operations has been improved, using the `Futures` trait.
+
+You can use the [`play.libs.concurrent.Futures`](api/java/play/libs/concurrent/Futures.html) interface to wrap a `CompletionStage` in a non-blocking timeout:
+
+```java
+class MyClass {
+ @Inject
+ public MyClass(Futures futures) {
+ this.futures = futures;
+ }
+
+ CompletionStage callWithOneSecondTimeout() {
+ return futures.timeout(computePIAsynchronously(), Duration.ofSeconds(1));
+ }
+}
+```
+
+or use [`play.api.libs.concurrent.Futures`](api/scala/play/api/libs/concurrent/Futures.html) trait in the Scala API:
+
+```scala
+import play.api.libs.concurrent.Futures._
+
+class MyController @Inject()(cc: ControllerComponents)(implicit futures: Futures) extends AbstractController(cc) {
+
+ def index = Action.async {
+ // withTimeout is an implicit type enrichment provided by importing Futures._
+ intensiveComputation().withTimeout(1.seconds).map { i =>
+ Ok("Got result: " + i)
+ }.recover {
+ case e: TimeoutException =>
+ InternalServerError("timeout")
+ }
+ }
+}
+```
+
+There is also a `delayed` method which only executes a `Future` after a specified delay, which works similarly to timeout.
+
+For more information, please see [[ScalaAsync]] or [[JavaAsync]].
+
+## CustomExecutionContext and Thread Pool Sizing
+
+This class defines a custom execution context that delegates to an `akka.actor.ActorSystem`. It is very useful for situations in which the default execution context should not be used, for example if a database or blocking I/O is being used. Detailed information can be found in the [[ThreadPools]] page, but Play 2.6.x adds a `CustomExecutionContext` class that handles the underlying Akka dispatcher lookup.
+
+## Updated Templates with Preconfigured CustomExecutionContexts
+
+All of the Play example templates on [Play's download page](https://playframework.com/download#examples) that use blocking APIs (i.e. Anorm, JPA) have been updated to use custom execution contexts where appropriate. For example, going to https://github.com/playframework/play-java-jpa-example/ shows that the [JPAPersonRepository](https://github.com/playframework/play-java-jpa-example/blob/4f962bc/app/models/JPAPersonRepository.java) class takes a `DatabaseExecutionContext` that wraps all the database operations.
+
+For thread pool sizing involving JDBC connection pools, you want a fixed thread pool size matching the connection pool, using a thread pool executor. Following the advice in [HikariCP's pool sizing page](https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing), you should configure your JDBC connection pool to double the number of physical cores, plus the number of disk spindles.
+
+The dispatcher settings used here come from [Akka dispatcher](https://doc.akka.io/docs/akka/2.5/dispatchers.html?language=java):
+
+```
+# db connections = ((physical_core_count * 2) + effective_spindle_count)
+fixedConnectionPool = 9
+
+database.dispatcher {
+ executor = "thread-pool-executor"
+ throughput = 1
+ thread-pool-executor {
+ fixed-pool-size = ${fixedConnectionPool}
+ }
+}
+```
+
+### Defining a CustomExecutionContext in Scala
+
+To define a custom execution context, subclass [`CustomExecutionContext`](api/scala/play/api/libs/concurrent/CustomExecutionContext.html) with the dispatcher name:
+
+```scala
+@Singleton
+class DatabaseExecutionContext @Inject()(system: ActorSystem)
+ extends CustomExecutionContext(system, "database.dispatcher")
+```
+
+Then have the execution context passed in as an implicit parameter:
+
+```scala
+class DatabaseService @Inject()(implicit executionContext: DatabaseExecutionContext) {
+ ...
+}
+```
+
+### Defining a CustomExecutionContext in Java
+
+To define a custom execution context, subclass [`CustomExecutionContext`](api/java/play/libs/concurrent/CustomExecutionContext.html) with the dispatcher name:
+
+```java
+import akka.actor.ActorSystem;
+import play.libs.concurrent.CustomExecutionContext;
+
+public class DatabaseExecutionContext
+ extends CustomExecutionContext {
+
+ @javax.inject.Inject
+ public DatabaseExecutionContext(ActorSystem actorSystem) {
+ // uses a custom thread pool defined in application.conf
+ super(actorSystem, "database.dispatcher");
+ }
+}
+```
+
+Then pass the JPA context in explicitly:
+
+```java
+public class JPAPersonRepository implements PersonRepository {
+
+ private final JPAApi jpaApi;
+ private final DatabaseExecutionContext executionContext;
+
+ @Inject
+ public JPAPersonRepository(JPAApi jpaApi, DatabaseExecutionContext executionContext) {
+ this.jpaApi = jpaApi;
+ this.executionContext = executionContext;
+ }
+
+ ...
+}
+```
+
+## Play `WSClient` Improvements
+
+There are substantial improvements to Play `WSClient`. Play `WSClient` is now a wrapper around the standalone [play-ws](https://github.com/playframework/play-ws) implementation, which can be used outside of Play. In addition, the underlying libraries involved in [play-ws](https://github.com/playframework/play-ws) have been [shaded](https://github.com/sbt/sbt-assembly#shading), so that the Netty implementation used in it does not conflict with Spark, Play or any other library that uses a different version of Netty.
+
+Finally, there is now support for [HTTP Caching](https://tools.ietf.org/html/rfc7234) if a cache implementation is present. Using an HTTP cache means savings on repeated requests to backend REST services, and is especially useful when combined with resiliency features such as [`stale-on-error` and `stale-while-revalidate`](https://tools.ietf.org/html/rfc5861).
+
+For more details, please see [[WsCache]] and the [[WS Migration Guide|WSMigration26]].
+
+## Play JSON improvements
+
+There are many improvements included in this release of the JSON library.
+
+### Ability to serialize tuples
+
+Now, tuples are able to be serialized by play-json, and there are `Reads` and `Writes` implementations in the implicit scope. Tuples are serialized to arrays, so `("foo", 2, "bar")` will render as `["foo", 2, "bar"]` in the JSON.
+
+### Scala.js support
+
+Play JSON 2.6.0 now supports Scala.js. You can add the dependency with:
+
+```scala
+libraryDependencies += "com.typesafe.play" %%% "play-json" % version
+```
+
+where `version` is the version you wish to use. The library should effectively work the same as it does on the JVM, except without support for JVM types.
+
+### Custom naming strategies for automated JSON mapping
+
+It is possible to customize the handlers generated by the `Json` macros (`reads`, `writes` or `format`). Thus, a naming strategy can be defined to map the JSON fields as wanted.
+
+To use a custom naming strategy you need to define implicit instances for `JsonConfiguration` and `JsonNaming`.
+
+Two naming strategies are provided: the default one, using as-is the names of the class properties, and the `JsonNaming.SnakeCase` case one.
+
+A strategy other than the default one can be used as following:
+
+```scala
+import play.api.libs.json._
+
+implicit val config = JsonConfiguration(SnakeCase)
+
+implicit val userFormat: OFormat[PlayUser] = Json.format[PlayUser]
+```
+
+In addition, custom naming strategies can be implemented by providing a `JsonNaming` implementation.
+
+## Testing Improvements
+
+Some utility classes have been added to the `play.api.test` package in 2.6.x to make functional testing easier with dependency injected components.
+
+### Injecting
+
+There are many functional tests that use the injector directly through the implicit `app`:
+
+```scala
+"test" in new WithApplication() {
+ val executionContext = app.injector.instanceOf[ExecutionContext]
+ ...
+}
+```
+
+Now with the [`Injecting`](api/scala/play/api/test/Injecting.html) trait, you can elide this:
+
+```scala
+"test" in new WithApplication() with Injecting {
+ val executionContext = inject[ExecutionContext]
+ ...
+}
+```
+
+### StubControllerComponents
+
+The [`StubControllerComponentsFactory`](api/scala/play/api/test/StubControllerComponentsFactory.html) creates a stub [`ControllerComponents`](api/scala/play/api/mvc/ControllerComponents.html) that can be used for unit testing a controller:
+
+```scala
+val controller = new MyController(stubControllerComponents())
+```
+
+### StubBodyParser
+
+The [`StubBodyParserFactory`](api/scala/play/api/test/StubBodyParserFactory.html) creates a stub [`BodyParser`](api/scala/play/api/mvc/BodyParser.html) that can be used for unit testing content:
+
+```scala
+val stubParser = stubBodyParser(AnyContent("hello"))
+```
+
+## File Upload Improvements
+
+Uploading files uses a `TemporaryFile` API which relies on storing files in a temporary filesystem, as specified in [[ScalaFileUpload]] / [[JavaFileUpload]], accessible through the `ref` attribute.
+
+Uploading files is an inherently dangerous operation, because unbounded file upload can cause the filesystem to fill up -- as such, the idea behind `TemporaryFile` is that it's only in scope at completion and should be moved out of the temporary file system as soon as possible. Any temporary files that are not moved are deleted.
+
+In 2.5.x, TemporaryFile were deleted as the file references were garbage collected, using `finalize`. However, under [certain conditions](https://github.com/playframework/playframework/issues/5545), garbage collection did not occur in a timely fashion. The background cleanup has been moved to use [FinalizableReferenceQueue](https://google.github.io/guava/releases/20.0/api/docs/com/google/common/base/FinalizableReferenceQueue.html) and PhantomReferences rather than use `finalize`.
+
+The Java and Scala APIs for `TemporaryFile` has been reworked so that all `TemporaryFile` references come from a `TemporaryFileCreator` trait, and the implementation can be swapped out as necessary, and there's now an [`atomicMoveWithFallback`](api/scala/play/api/libs/Files$$TemporaryFile.html#atomicMoveWithFallback\(to:java.nio.file.Path\):play.api.libs.Files.TemporaryFile) method that uses `StandardCopyOption.ATOMIC_MOVE` if available.
+
+### TemporaryFileReaper
+
+There's also now a [`play.api.libs.Files.TemporaryFileReaper`](api/scala/play/api/libs/Files$$DefaultTemporaryFileReaper.html) that can be enabled to delete temporary files on a scheduled basis using the Akka scheduler, distinct from the garbage collection method.
+
+The reaper is disabled by default, and is enabled through `application.conf`:
+
+```
+play.temporaryFile {
+ reaper {
+ enabled = true
+ initialDelay = "5 minutes"
+ interval = "30 seconds"
+ olderThan = "30 minutes"
+ }
+}
+```
+
+The above configuration will delete files that are more than 30 minutes old, using the "olderThan" property. It will start the reaper five minutes after the application starts, and will check the filesystem every 30 seconds thereafter. The reaper is not aware of any existing file uploads, so protracted file uploads may run into the reaper if the system is not carefully configured.
diff --git a/manual/releases/release26/index.toc b/manual/releases/release26/index.toc
new file mode 100644
index 00000000..efbc2ec5
--- /dev/null
+++ b/manual/releases/release26/index.toc
@@ -0,0 +1,2 @@
+Highlights26:What's new?
+!migration26:Migration Guides
diff --git a/manual/releases/release26/migration26/CacheMigration26.md b/manual/releases/release26/migration26/CacheMigration26.md
new file mode 100644
index 00000000..210732a0
--- /dev/null
+++ b/manual/releases/release26/migration26/CacheMigration26.md
@@ -0,0 +1,84 @@
+
+# Cache APIs Migration
+
+## New packages
+
+Now `cache` has been split into a `cacheApi` component with just the API, and `ehcache` that contains the Ehcache implementation. If you are using the default Ehcache implementation, simply change `cache` to `ehcache` in your `build.sbt`:
+
+```
+libraryDependencies ++= Seq(
+ ehcache
+)
+```
+
+If you are defining a custom cache API, or are writing a cache implementation module, you can just depend on the API:
+
+```
+libraryDependencies ++= Seq(
+ cacheApi
+)
+```
+
+## Removed APIs
+
+The deprecated Java class `play.cache.Cache` was removed and you now must inject an `play.cache.SyncCacheApi` or `play.cache.AsyncCacheApi`.
+
+## New Sync and Async Cache APIs
+
+The Cache API has been rewritten to have a synchronous and an asynchronous version. The old APIs will still work but they are now deprecated.
+
+### Java API
+
+The interface `play.cache.CacheApi` is now deprecated and should be replaced by `play.cache.SyncCacheApi` or `play.cache.AsyncCacheApi`.
+
+To use, `play.cache.SyncCacheApi` just inject it:
+
+```java
+public class SomeController extends Controller {
+
+ private SyncCacheApi cacheApi;
+
+ @Inject
+ public SomeController(SyncCacheApi cacheApi) {
+ this.cacheApi = cacheApi;
+ }
+}
+```
+
+And then there is the asynchronous version of the API:
+
+```java
+public class SomeController extends Controller {
+
+ private AsyncCacheApi cacheApi;
+
+ @Inject
+ public SomeController(AsyncCacheApi cacheApi) {
+ this.cacheApi = cacheApi;
+ }
+}
+```
+
+See more details about how to use both APIs at [[specific documentation|JavaCache]].
+
+### Scala API
+
+The trait `play.api.cache.CacheApi` is now deprecated and should be replaced by `play.api.cache.SyncCacheApi` or `play.api.cache.AsyncCacheApi`.
+
+To use `play.api.cache.SyncCacheApi`, just inject it:
+
+```scala
+class Application @Inject() (cache: SyncCacheApi) extends Controller {
+
+}
+```
+
+Basically the same for `play.api.cache.AsyncCacheApi`:
+
+```scala
+class Application @Inject() (cache: AsyncCacheApi) extends Controller {
+
+}
+```
+
+See more details about how to use both APIs at [[specific documentation|ScalaCache]].
diff --git a/manual/releases/release26/migration26/JPAMigration26.md b/manual/releases/release26/migration26/JPAMigration26.md
new file mode 100644
index 00000000..a348d1b9
--- /dev/null
+++ b/manual/releases/release26/migration26/JPAMigration26.md
@@ -0,0 +1,25 @@
+
+# JPA Migration
+
+## Removed Deprecated Methods
+
+The following deprecated methods have been removed in Play 2.6.
+
+* `play.db.jpa.JPA.jpaApi`
+* `play.db.jpa.JPA.em(key)`
+* `play.db.jpa.JPA.bindForAsync(em)`
+* `play.db.jpa.JPA.withTransaction`
+
+Please use a `JPAApi` injected instance as specified in [[Using play.db.jpa.JPAApi|JavaJPA#Using-play.db.jpa.JPAApi]].
+
+## Deprecated JPA Class
+
+As of 2.6.1, the `play.db.jpa.JPA` class has been deprecated, as it uses global state under the hood. The deprecation was mistakenly left out of 2.6.0.
+
+Please use a `JPAApi` injected instance as specified in [[Using play.db.jpa.JPAApi|JavaJPA#Using-play.db.jpa.JPAApi]].
+
+## Added Async Warning
+
+Added the following to [[JavaJPA]]:
+
+> Using JPA directly in an Action will limit your ability to use Play asynchronously. Consider arranging your code so that all access to to JPA is wrapped in a custom [[execution context|ThreadPools]], and returns [`java.util.concurrent.CompletionStage`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html) to Play.
diff --git a/manual/releases/release26/migration26/JavaConfigMigration26.md b/manual/releases/release26/migration26/JavaConfigMigration26.md
new file mode 100644
index 00000000..62101734
--- /dev/null
+++ b/manual/releases/release26/migration26/JavaConfigMigration26.md
@@ -0,0 +1,96 @@
+
+
+# Java Configuration API Migration
+
+The class `play.Configuration` was deprecated in favor of using [Typesafe Config](https://github.com/typesafehub/config) directly. So, instead of using `play.Configuration` you must now use [`com.typesafe.config.Config`](https://lightbend.github.io/config/latest/api/com/typesafe/config/Config.html). For example:
+
+Before:
+```java
+import play.Configuration;
+public class Foo {
+ private final Configuration configuration;
+
+ @javax.inject.Inject
+ public Foo(Configuration configuration) {
+ this.configuration = configuration;
+ }
+}
+```
+
+After:
+```java
+import com.typesafe.config.Config;
+
+public class Foo {
+ private final Config config;
+
+ @javax.inject.Inject
+ public Foo(Config config) {
+ this.config = config;
+ }
+}
+```
+
+## Config values should always be defined
+
+The main difference between the `Config` and `play.Configuration` APIs is how to handle default values. [Typesafe Config advocates](https://github.com/typesafehub/config/tree/v1.3.1#how-to-handle-defaults) that all configuration keys must be declared in your `.conf` files, including the default values.
+
+Play itself is using `reference.conf` files to declare default values for all the possible configurations. To avoid the hassle of handling missing values, you can do the same if you are distributing a library. When the configuration is read, the `application.conf` files are layered on top of the `reference.conf` configuration. For example:
+
+Before (`configuration` is `play.Configuration`):
+```java
+// Here we have the default values inside the code, which is not the idiomatic way when using Typesafe Config.
+Long timeout = configuration.getMilliseconds("my.service.timeout", 5000); // 5 seconds
+```
+
+After:
+```
+# This is declared in `conf/reference.conf`.
+my.service.timeout = 5 seconds
+```
+
+And you can eventually override the value in your `application.conf` file:
+
+```
+# This will override the value declared in reference.conf
+my.service.timeout = 10 seconds
+```
+
+This is especially useful when creating modules, since your module can provide reference values that are easy to override. Your Java code will then look like:
+
+```java
+Long timeout = config.getDuration("my.service.timeout", TimeUnit.MILLISECONDS);
+```
+
+where `config` is your `com.typesafe.config.Config` instance.
+
+## Manually checking values
+
+If you don't want or if you cannot have default values for some reason, you can use [`Config.hasPath`](https://lightbend.github.io/config/latest/api/com/typesafe/config/Config.html#hasPath-java.lang.String-) or [`Config.hasPathOrNull`](https://lightbend.github.io/config/latest/api/com/typesafe/config/Config.html#hasPathOrNull-java.lang.String-) to check if the value is configured before accessing it. This is a better option if the configuration is required but you can't provide a reference (default) value:
+
+```java
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigException;
+
+public class EmailServerConfig {
+
+ private static final String SERVER_ADDRESS_KEY = "my.smtp.server.address";
+
+ private final Config config;
+
+ @javax.inject.Inject
+ public EmailServerConfig(Config config) {
+ this.config = config;
+ }
+
+ // The relevant code is here. First use `hasPath` to check if the configuration
+ // exists and, if not, throw an exception.
+ public String getSmtpAddress() {
+ if (config.hasPath(SERVER_ADDRESS_KEY)) {
+ return config.getString(SERVER_ADDRESS_KEY);
+ } else {
+ throw new ConfigException.Missing(SERVER_ADDRESS_KEY);
+ }
+ }
+}
+```
diff --git a/manual/releases/release26/migration26/MessagesMigration26.md b/manual/releases/release26/migration26/MessagesMigration26.md
new file mode 100644
index 00000000..efa26769
--- /dev/null
+++ b/manual/releases/release26/migration26/MessagesMigration26.md
@@ -0,0 +1,320 @@
+
+# I18N API Migration
+
+There are a number of changes to the I18N API to make working with messages and languages easier to use, particularly with forms and templates.
+
+## Java API
+
+### Refactored Messages API to interfaces
+
+The `play.i18n` package has changed to make access to [`Messages`](api/java/play/i18n/Messages.html) easier. These changes should be transparent to the user, but are provided here for teams extending the I18N API.
+
+[`Messages`](api/java/play/i18n/Messages.html) is now an interface, and there is a [`MessagesImpl`](api/java/play/i18n/MessagesImpl.html) class that implements that interface.
+
+### Deprecated / Removed Methods
+
+The static deprecated methods in [`play.i18n.Messages`](api/java/play/i18n/Messages.html) have been removed in 2.6.x, as there are equivalent methods on the [`MessagesApi`](api/java/play/i18n/MessagesApi.html) instance.
+
+## Scala API
+
+### Removed Implicit Default Lang
+
+The [`Lang`](api/scala/play/api/i18n/Lang.html) singleton object has a `defaultLang` that points to the JVM default Locale. Pre 2.6.x, `defaultLang` was an implicit value, with the result that it could be used in implicit scope resolution if no `Lang` was found in local scope. This setting was too general and resulted in bugs where `defaultLang` was being used instead of a request's locale, if the request was not declared as implicit.
+
+As a result, the implicit has been removed, and so what was:
+
+```scala
+object Lang {
+ implicit lazy val defaultLang: Lang = Lang(java.util.Locale.getDefault)
+}
+```
+
+is now:
+
+```scala
+object Lang {
+ lazy val defaultLang: Lang = Lang(java.util.Locale.getDefault)
+}
+```
+
+Any code that was relying on this implicit should use `Lang.defaultLang` explicitly.
+
+### Refactored Messages API to traits
+
+ The `play.api.i18n` package has changed to make access to [`Messages`](api/scala/play/api/i18n/Messages.html) instances easier and reduce the number of implicits in play. These changes should be transparent to the user, but are provided here for teams extending the I18N API.
+
+[`Messages`](api/scala/play/api/i18n/Messages.html) is now a trait (rather than a case class). The case class is now [`MessagesImpl`](api/scala/play/api/i18n/MessagesImpl.html), which implements [`Messages`](api/scala/play/api/i18n/Messages.html).
+
+### I18nSupport Implicit Conversion
+
+If you are upgrading directly from Play 2.5 to Play 2.6, you should know that `I18nSupport` support has changed in 2.6.x. In 2.5.x, it was possible through a series of implicits to use a "language default" `Messages` instance if the request was not declared to be in implicit scope:
+
+```scala
+ def listWidgets = Action {
+ val lang = implicitly[Lang] // Uses Lang.defaultLang
+ val messages = implicitly[Messages] // Uses I18nSupport.lang2messages(Lang.defaultLang)
+ // implicit parameter messages: Messages in requiresMessages template, but no request!
+ val content = views.html.requiresMessages(form)
+ Ok(content)
+ }
+```
+
+The [`I18nSupport`](api/scala/play/api/i18n/I18nSupport.html) implicit conversion now requires an implicit request or request header in scope in order to correctly determine the preferred locale and language for the request.
+
+This means if you have the following:
+
+```scala
+def index = Action {
+
+}
+```
+
+You need to change it to:
+
+```scala
+def index = Action { implicit request =>
+
+}
+```
+
+This will allow i18n support to see the request's locale and provide error messages and validation alerts in the user's language.
+
+### Smoother I18nSupport
+
+Using a form inside a controller is a smoother experience in 2.6.x. [`ControllerComponents`](api/scala/play/api/mvc/ControllerComponents.html) contains a [`MessagesApi`](api/scala/play/api/i18n/MessagesApi.html) instance, which is exposed by [`AbstractController`](api/scala/play/api/mvc/AbstractController.html). This means that the [`I18nSupport`](api/scala/play/api/i18n/I18nSupport.html) trait does not require an explicit `val messagesApi: MessagesApi` declaration, as it did in Play 2.5.x.
+
+```scala
+class FormController @Inject()(components: ControllerComponents)
+ extends AbstractController(components) with I18nSupport {
+
+ import play.api.data.validation.Constraints._
+
+ val userForm = Form(
+ mapping(
+ "name" -> text.verifying(nonEmpty),
+ "age" -> number.verifying(min(0), max(100))
+ )(UserData.apply)(UserData.unapply)
+ )
+
+ def index = Action { implicit request =>
+ // use request2messages implicit conversion method
+ Ok(views.html.user(userForm))
+ }
+
+ def showMessage = Action { request =>
+ // uses type enrichment
+ Ok(request.messages("hello.world"))
+ }
+
+ def userPost = Action { implicit request =>
+ userForm.bindFromRequest.fold(
+ formWithErrors => {
+ BadRequest(views.html.user(formWithErrors))
+ },
+ user => {
+ Redirect(routes.FormController.index()).flashing("success" -> s"User is ${user}!")
+ }
+ )
+ }
+}
+```
+
+Note there is now also type enrichment in [`I18nSupport`](api/scala/play/api/i18n/I18nSupport.html) which adds `request.messages` and `request.lang`. This can be added either by extending from [`I18nSupport`](api/scala/play/api/i18n/I18nSupport.html), or by `import I18nSupport._`. The import version does not contain the `request2messages` implicit conversion.
+
+## Integrated Messages with MessagesProvider
+
+A new [`MessagesProvider`](api/scala/play/api/i18n/MessagesProvider.html) trait is available, which exposes a [`Messages`](api/scala/play/api/i18n/Messages.html) instance.
+
+```scala
+trait MessagesProvider {
+ def messages: Messages
+}
+```
+
+[`MessagesImpl`](api/scala/play/api/i18n/MessagesImpl.html) implements [`Messages`](api/scala/play/api/i18n/Messages.html) and [`MessagesProvider`](api/scala/play/api/i18n/MessagesProvider.html), and returns itself by default.
+
+All the template helpers now take [`MessagesProvider`](api/scala/play/api/i18n/MessagesProvider.html) as an implicit parameter, rather than a straight `Messages` object, i.e. `inputText.scala.html` takes the following:
+
+```scala
+@(field: play.api.data.Field, args: (Symbol,Any)*)(implicit handler: FieldConstructor, messagesProvider: play.api.i18n.MessagesProvider)
+```
+
+The benefit to using a [`MessagesProvider`](api/scala/play/api/i18n/MessagesProvider.html) is that otherwise, if you used implicit `Messages`, you would have to introduce implicit conversions from other types like `Request` in places where those implicits could be confusing.
+
+### MessagesRequest and MessagesAbstractController
+
+To assist, there's [`MessagesRequest`](api/scala/play/api/mvc/MessagesRequest.html), which is a [`WrappedRequest`](api/scala/play/api/mvc/WrappedRequest.html) that implements [`MessagesProvider`](api/scala/play/api/i18n/MessagesProvider.html) and provides the preferred language.
+
+You can access a [`MessagesRequest`](api/scala/play/api/mvc/MessagesRequest.html) by using a [`MessagesActionBuilder`](api/scala/play/api/mvc/MessagesActionBuilder.html):
+
+```scala
+
+class MyController @Inject()(
+ messagesAction: MessagesActionBuilder,
+ cc: ControllerComponents
+ ) extends AbstractController(cc) {
+ def index = messagesAction { implicit request: MessagesRequest[AnyContent] =>
+ Ok(views.html.formTemplate(form)) // twirl template with form builders
+ }
+}
+
+```
+
+Or you can use [`MessagesAbstractController`](api/scala/play/api/mvc/MessagesAbstractController.html), which swaps out the default `Action` that provides `MessagesRequest` instead of `Request` in the block:
+
+```scala
+
+class MyController @Inject() (
+ mcc: MessagesControllerComponents
+) extends MessagesAbstractController(mcc) {
+
+ def index = Action { implicit request: MessagesRequest[AnyContent] =>
+ Ok(s"The messages are ${request.messages}")
+ }
+}
+
+```
+
+Here's a complete example using a form with a CSRF action (assuming that you have CSRF filter disabled):
+
+```scala
+
+class MyController @Inject() (
+ addToken: CSRFAddToken,
+ checkToken: CSRFCheck,
+ mcc: MessagesControllerComponents
+) extends MessagesAbstractController(mcc) {
+
+ import play.api.data.Form
+ import play.api.data.Forms._
+
+ val userForm = Form(
+ mapping(
+ "name" -> text,
+ "age" -> number
+ )(UserData.apply)(UserData.unapply)
+ )
+
+ def index = addToken {
+ Action { implicit request =>
+ Ok(views.html.formpage(userForm))
+ }
+ }
+
+ def userPost = checkToken {
+ Action { implicit request =>
+ userForm.bindFromRequest.fold(
+ formWithErrors => {
+ play.api.Logger.info(s"unsuccessful user submission")
+ BadRequest(views.html.formpage(formWithErrors))
+ },
+ user => {
+ play.api.Logger.info(s"successful user submission ${user}")
+ Redirect(routes.MyController.index()).flashing("success" -> s"User is ${user}!")
+ }
+ )
+ }
+ }
+}
+
+```
+
+Because `MessagesRequest` is a `MessagesProvider`, you only have to define the request as implicit and it will carry through to the template. This is especially useful when CSRF checks are involved. The `formpage.scala.html` page is as follow:
+
+```scala
+
+@(userForm: Form[UserData])(implicit request: MessagesRequestHeader)
+
+@helper.form(action = routes.MyController.userPost()) {
+ @views.html.helper.CSRF.formField
+ @helper.inputText(userForm("name"))
+ @helper.inputText(userForm("age"))
+
+}
+
+```
+
+Note that because the body of the `MessageRequest` is not relevant to the template, we can use `MessagesRequestHeader` here instead of `MessageRequest[_]`.
+
+Please see [[passing messages to form helpers|ScalaForms#Passing-MessagesProvider-to-Form-Helpers]] for more details.
+
+### DefaultMessagesApi component
+
+The default implementation of [`MessagesApi`](api/scala/play/api/i18n/MessagesApi.html) is [`DefaultMessagesApi`](api/scala/play/api/i18n/DefaultMessagesApi.html). [`DefaultMessagesApi`](api/scala/play/api/i18n/DefaultMessagesApi.html) used to take [`Configuration`](api/scala/play/api/Configuration.html) and [`Environment`](api/scala/play/api/Environment.html) directly, which made it awkward to deal with in forms. For unit testing purposes, [`DefaultMessagesApi`](api/scala/play/api/i18n/DefaultMessagesApi.html) can be instantiated without arguments, and will take a raw map.
+
+```scala
+
+import play.api.data.Forms._
+import play.api.data._
+import play.api.i18n._
+
+val messagesApi = new DefaultMessagesApi(
+ Map("en" ->
+ Map("error.min" -> "minimum!")
+ )
+)
+implicit val request = {
+ play.api.test.FakeRequest("POST", "/")
+ .withFormUrlEncodedBody("name" -> "Play", "age" -> "-1")
+}
+implicit val messages = messagesApi.preferred(request)
+
+def errorFunc(badForm: Form[UserData]) = {
+ BadRequest(badForm.errorsAsJson)
+}
+
+def successFunc(userData: UserData) = {
+ Redirect("/").flashing("success" -> "success form!")
+}
+
+val result = Future.successful(form.bindFromRequest().fold(errorFunc, successFunc))
+Json.parse(contentAsString(result)) must beEqualTo(Json.obj("age" -> Json.arr("minimum!")))
+
+```
+
+For functional tests that involve configuration, the best option is to use `WithApplication` and pull in an injected [`MessagesApi`](api/scala/play/api/i18n/MessagesApi.html):
+
+```scala
+
+import play.api.test.{ PlaySpecification, WithApplication }
+import play.api.i18n._
+
+class MessagesSpec extends PlaySpecification {
+
+ sequential
+
+ implicit val lang = Lang("en-US")
+
+ "Messages" should {
+ "provide default messages" in new WithApplication(_.requireExplicitBindings()) {
+ val messagesApi = app.injector.instanceOf[MessagesApi]
+ val javaMessagesApi = app.injector.instanceOf[play.i18n.MessagesApi]
+
+ val msg = messagesApi("constraint.email")
+ val javaMsg = javaMessagesApi.get(new play.i18n.Lang(lang), "constraint.email")
+
+ msg must ===("Email")
+ msg must ===(javaMsg)
+ }
+ "permit default override" in new WithApplication(_.requireExplicitBindings()) {
+ val messagesApi = app.injector.instanceOf[MessagesApi]
+ val msg = messagesApi("constraint.required")
+
+ msg must ===("Required!")
+ }
+ }
+}
+
+```
+
+If you need to customize the configuration, it's better to add configuration values into the [`GuiceApplicationBuilder`](api/scala/play/api/inject/guice/GuiceApplicationBuilder.html) rather than use the [`DefaultMessagesApiProvider`](api/scala/play/api/i18n/DefaultMessagesApiProvider.html) directly.
+
+### Deprecated Methods
+
+`play.api.i18n.Messages.Implicits.applicationMessagesApi` and `play.api.i18n.Messages.Implicits.applicationMessages` have been deprecated, because they rely on an implicit `Application` instance.
+
+The `play.api.mvc.Controller.request2lang` method has been deprecated, because it was using a global `Application` under the hood.
+
+The `play.api.i18n.I18nSupport.request2Messages` implicit conversion method has been moved to `I18NSupportLowPriorityImplicits.request2Messages`, and deprecated in favor of `request.messages` type enrichment, which is clearer overall.
+
+The `I18NSupportLowPriorityImplicits.lang2Messages` implicit conversion has been moved out to `LangImplicits.lang2Messages`, because of confusion when both implicit Request and a Lang were in scope. Please extend the [`play.api.i18n.LangImplicits`](api/scala/play/api/i18n/LangImplicits.html) trait specifically if you want to create a `Messages` from an implicit `Lang`.
diff --git a/manual/releases/release26/migration26/Migration26.md b/manual/releases/release26/migration26/Migration26.md
new file mode 100644
index 00000000..d9eb015c
--- /dev/null
+++ b/manual/releases/release26/migration26/Migration26.md
@@ -0,0 +1,1241 @@
+
+# Play 2.6 Migration Guide
+
+This is a guide for migrating from Play 2.5 to Play 2.6. If you need to migrate from an earlier version of Play then you must first follow the [[Play 2.5 Migration Guide|Migration25]].
+
+## How to migrate
+
+The following steps need to be taken to update your sbt build before you can load/run a Play project in sbt.
+
+### Play upgrade
+
+Update the Play version number in `project/plugins.sbt` to upgrade Play:
+
+```scala
+addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.x")
+```
+
+Where the "x" in `2.6.x` is the minor version of Play you want to use, for instance `2.6.0`.
+
+### sbt upgrade to 0.13.15
+
+Play 2.6 requires upgrading to at least sbt 0.13.15. The 0.13.15 release of sbt has a number of [improvements and bug fixes](https://www.scala-sbt.org/0.13/docs/sbt-0.13-Tech-Previews.html#sbt+0.13.15) (see also the changes in [sbt 0.13.13](https://www.scala-sbt.org/0.13/docs/sbt-0.13-Tech-Previews.html#sbt+0.13.13)).
+
+sbt 1.x is supported beginning with Play 2.6.6. If you are using other sbt plugins, you may need to check if there is a newer version compatible with sbt 1.x
+
+To update, change your `project/build.properties` so that it reads:
+
+```
+sbt.version=0.13.15
+```
+
+### Guice DI support moved to separate module
+
+In Play 2.6, the core Play module no longer includes Guice. You will need to configure the Guice module by adding `guice` to your `libraryDependencies`:
+
+```scala
+libraryDependencies += guice
+```
+
+### OpenID support moved to separate module
+
+In Play 2.6, the core Play module no longer includes the OpenID support in `play.api.libs.openid` (Scala) and `play.libs.openid` (Java). To use these packages add `openId` to your `libraryDependencies`:
+
+```scala
+libraryDependencies += openId
+```
+
+### Play JSON moved to separate project
+
+Play JSON has been moved to a separate library hosted at https://github.com/playframework/play-json. Since Play JSON has no dependencies on the rest of Play, the main change is that the `json` value from `PlayImport` will no longer work in your sbt build. Instead, you'll have to specify the library manually:
+
+```scala
+libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.0"
+```
+
+Also, play-json has a separate release cycle from the core Play library, so the version is no longer in sync with the Play version.
+
+### Play Iteratees moved to separate project
+
+Play Iteratees has been moved to a separate library hosted at https://github.com/playframework/play-iteratees. Since Play Iteratees has no dependencies on the rest of Play, the main change is that the you'll have to specify the library manually:
+
+```scala
+libraryDependencies += "com.typesafe.play" %% "play-iteratees" % "2.6.1"
+```
+
+The project also has a sub project that integrates Iteratees with [Reactive Streams](http://www.reactive-streams.org/). You may need to add the following dependency as well:
+
+```scala
+libraryDependencies += "com.typesafe.play" %% "play-iteratees-reactive-streams" % "2.6.1"
+```
+
+> **Note**: The helper class `play.api.libs.streams.Streams` was moved to `play-iteratees-reactive-streams` and now is called `play.api.libs.iteratee.streams.IterateeStreams`. So you may need to add the Iteratees dependencies and also use the new class where necessary.
+
+Finally, Play Iteratees has a separate versioning scheme, so the version is no longer in sync with the Play version.
+
+## Akka HTTP as the default server engine
+
+Play now uses the [Akka-HTTP](https://doc.akka.io/docs/akka-http/current/?language=scala) server engine as the default backend. If you need to change it back to Netty for some reason (for example, if you are using Netty's [native transports](https://netty.io/wiki/native-transports.html)), see how to do that in [[Netty Server|NettyServer]] documentation.
+
+You can read more at [[Akka HTTP Server Backend|AkkaHttpServer]].
+
+### Akka HTTP server timeouts
+
+Play 2.5.x does not have a request timeout configuration for [[Netty Server|NettyServer]], which was the default server backend. But Akka HTTP has timeouts for both idle connections and requests (see more details in [[Akka HTTP Settings|SettingsAkkaHttp]] documentation). [Akka HTTP docs](https://doc.akka.io/docs/akka-http/current/common/timeouts.html?language=scala#akka-http-timeouts) states that:
+
+> Akka HTTP comes with a variety of built-in timeout mechanisms to protect your servers from malicious attacks or programming mistakes.
+
+And you can see the default values for `akka.http.server.idle-timeout`, `akka.http.server.request-timeout` and `akka.http.server.bind-timeout` [here](https://doc.akka.io/docs/akka-http/current/configuration.html?language=scala). Play has [[its own configurations to define timeouts|SettingsAkkaHttp]], so if you start to see a number of `503 Service Unavailable`, you can change the configurations to values that are more reasonable to your application, for example:
+
+```
+play.server.http.idleTimeout = 60s
+play.server.akka.requestTimeout = 40s
+```
+
+## Scala `Mode` changes
+
+Scala [`Mode`](api/scala/play/api/Mode.html) was refactored from an Enumeration to a hierarchy of case objects. Most of the Scala code won't change because of this refactoring. But, if you are accessing the Scala `Mode` values in your Java code, you will need to change it from:
+
+```java
+// Consider this Java code
+play.api.Mode scalaMode = play.api.Mode.Test();
+```
+
+Must be rewritten to:
+
+```java
+// Consider this Java code
+play.api.Mode scalaMode = play.Mode.TEST.asScala();
+```
+
+It is also easier to convert between Java and Scala modes:
+
+```java
+// In your Java code
+play.api.Mode scalaMode = play.Mode.DEV.asScala();
+```
+
+Or in your Scala code:
+
+```scala
+play.Mode javaMode = play.api.Mode.Dev.asJava
+```
+
+Also, `play.api.Mode.Mode` is now deprecated and you should use `play.api.Mode` instead.
+
+## `Writeable[JsValue]` changes
+
+Previously, the default Scala `Writeable[JsValue]` allowed you to define an implicit `Codec`, which would allow you to write using a different charset. This could be a problem since `application/json` does not act like text-based content types. It only allows Unicode charsets (`UTF-8`, `UTF-16` and `UTF-32`) and does not define a `charset` parameter like many text-based content types.
+
+Now, the default `Writeable[JsValue]` takes no implicit parameters and always writes to `UTF-8`. This covers the majority of cases, since most users want to use UTF-8 for JSON. It also allows us to easily use more efficient built-in methods for writing JSON to a byte array.
+
+If you need the old behavior back, you can define a `Writeable` with an arbitrary codec using `play.api.http.Writeable.writeableOf_JsValue(codec, contentType)` for your desired Codec and Content-Type.
+
+## Scala Controller changes
+
+The idiomatic Play controller has in the past required global state. The main places that was needed was in the global [`Action`](api/scala/play/api/mvc/Action$.html) object and [`BodyParsers#parse`](api/scala/play/api/mvc/BodyParsers.html#parse:play.api.mvc.PlayBodyParsers) method.
+
+We have provided several new controller classes with new ways of injecting that state, providing the same syntax:
+ - [`BaseController`](api/scala/play/api/mvc/BaseController.html): a trait with an abstract [`ControllerComponents`](api/scala/play/api/mvc/ControllerComponents.html) that can be provided by an implementing class.
+ - [`AbstractController`](api/scala/play/api/mvc/AbstractController.html): an abstract class extending [`BaseController`](api/scala/play/api/mvc/BaseController.html) with a [`ControllerComponents`](api/scala/play/api/mvc/ControllerComponents.html) constructor parameter that can be injected using constructor injection.
+ - [`InjectedController`](api/scala/play/api/mvc/InjectedController.html): a trait, extending [`BaseController`](api/scala/play/api/mvc/BaseController.html), that obtains the [`ControllerComponents`](api/scala/play/api/mvc/ControllerComponents.html) through method injection (calling a `setControllerComponents` method). If you are using a runtime DI framework like Guice, this is done automatically.
+
+[`ControllerComponents`](api/scala/play/api/mvc/ControllerComponents.html) is simply meant to bundle together components typically used in a controller. You may also wish to create your own base controller for your app by extending [`ControllerHelpers`](api/scala/play/api/mvc/ControllerHelpers.html) and injecting your own bundle of components. Play does not require your controllers to implement any particular trait.
+
+Note that [`BaseController`](api/scala/play/api/mvc/BaseController.html) makes [`Action`](api/scala/play/api/mvc/Action.html) and `parse` refer to injected instances rather than the global objects, which is usually what you want to do.
+
+Here's an example of code using [`AbstractController`](api/scala/play/api/mvc/AbstractController.html):
+
+```scala
+class FooController @Inject() (components: ControllerComponents)
+ extends AbstractController(components) {
+
+ // Action and parse now use the injected components
+ def foo = Action(parse.json) {
+ Ok
+ }
+}
+```
+
+and using [`BaseController`](api/scala/play/api/mvc/BaseController.html):
+
+```scala
+class FooController @Inject() (val controllerComponents: ControllerComponents) extends BaseController {
+
+ // Action and parse now use the injected components
+ def foo = Action(parse.json) {
+ Ok
+ }
+}
+```
+
+and [`InjectedController`](api/scala/play/api/mvc/InjectedController.html):
+
+```scala
+class FooController @Inject() () extends InjectedController {
+
+ // Action and parse now use the injected components
+ def foo = Action(parse.json) {
+ Ok
+ }
+}
+```
+
+[`InjectedController`](api/scala/play/api/mvc/InjectedController.html) gets its [`ControllerComponents`](api/scala/play/api/mvc/ControllerComponents.html) by calling the `setControllerComponents` method, which is called automatically by JSR-330 compliant dependency injection. We do not recommend using [`InjectedController`](api/scala/play/api/mvc/InjectedController.html) with compile-time injection. If you plan to extensively unit test your controllers manually, we also recommend avoiding [`InjectedController`](api/scala/play/api/mvc/InjectedController.html) since it hides the dependency.
+
+If you prefer to pass the individual dependencies manually, you can do that instead and extend [`ControllerHelpers`](api/scala/play/api/mvc/ControllerHelpers.html), which has no dependencies or state. Here's an example:
+
+```scala
+class Controller @Inject() (
+ action: DefaultActionBuilder,
+ parse: PlayBodyParsers,
+ messagesApi: MessagesApi
+ ) extends ControllerHelpers {
+ def index = action(parse.text) { request =>
+ Ok(messagesApi.preferred(request)("hello.world"))
+ }
+}
+```
+
+## Scala ActionBuilder and BodyParser changes
+
+The Scala [`ActionBuilder`](api/scala/play/api/mvc/ActionBuilder.html) trait has been modified to specify the type of the body as a type parameter, and add an abstract `parser` member as the default body parsers. You will need to modify your ActionBuilders and pass the body parser directly.
+
+The [`Action`](api/scala/play/api/mvc/Action$.html) global object and [`BodyParsers#parse`](api/scala/play/api/mvc/BodyParsers.html#parse:play.api.mvc.PlayBodyParsers) are now deprecated. They are replaced by injectable traits, [`DefaultActionBuilder`](api/scala/play/api/mvc/DefaultActionBuilder.html) and [`PlayBodyParsers`](api/scala/play/api/mvc/PlayBodyParsers.html) respectively. If you are inside a controller, they are automatically provided by the new [`BaseController`](api/scala/play/api/mvc/BaseController.html) trait (see [the controller changes](#Scala-Controller-changes) above).
+
+## Cookies
+
+For Java users, we now recommend using [`play.mvc.Http.Cookie.builder`](api/java/play/mvc/Http.Cookie.html#builder-java.lang.String-java.lang.String-) to create new cookies, for example:
+
+```java
+Http.Cookie cookie = Cookie.builder("color", "blue")
+ .withMaxAge(3600)
+ .withSecure(true)
+ .withHttpOnly(true)
+ .withSameSite(SameSite.STRICT)
+ .build();
+```
+
+This is more readable than a plain constructor call, and will be source-compatible if we add/remove cookie attributes in the future.
+
+### SameSite attribute, enabled for session and flash
+
+Cookies now can have an additional [`SameSite` attribute](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00), which can be used to prevent CSRF. There are three possible states:
+
+ - No `SameSite`, meaning cookies will be sent for all requests to that domain.
+ - `SameSite=Strict`, meaning the cookie will only be sent for same-site requests (coming from another page on the site) not cross-site requests
+ - `SameSite=Lax`, meaning the cookie will be sent for cross-site requests as top-level navigation, but otherwise only for same-site requests. This will do the correct thing for most sites, but won't prevent certain types of attacks, such as those executed by launching popup windows.
+
+In addition, we have moved the session and flash cookies to use `SameSite=Lax` by default. You can tweak this using configuration. For example:
+
+```
+play.http.session.sameSite = null // no same-site for session
+play.http.flash.sameSite = "strict" // strict same-site for flash
+```
+
+> **Note**: this feature is currently [not supported by many browsers](https://caniuse.com/#feat=same-site-cookie-attribute), so you should not rely on it. Chrome and Opera are the only major browsers to support SameSite right now.
+
+### __Host and __Secure prefixes
+
+We've also added support for the [\__Host and \__Secure cookie name prefixes](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00#section-3).
+
+This will only affect you if you happen to be using these prefixes for cookie names. If you are, Play will warn when serializing and deserializing those cookies if the proper attributes are not set, then set them for you automatically. To remove the warning, either cease using those prefixes for your cookies, or be sure to set the attributes as follows:
+
+- Cookies named with `__Host-` should set `Path=/` and `Secure` attributes.
+- Cookies named with `__Secure-` should set the `Secure` attribute.
+
+## Assets
+
+### Binding Assets with compile-time DI
+
+If you are using compile-time DI, you should mix in [`controllers.AssetsComponents`](api/scala/controllers/AssetsComponents.html) and use that to obtain the `assets: Assets` controller instance:
+
+```scala
+class MyComponents(context: Context) extends BuiltInComponentsFromContext(context) with AssetsComponents {
+ lazy val router = new Routes(httpErrorHandler, assets)
+}
+```
+
+If you have an existing `lazy val assets: Assets` you can remove it.
+
+### Assets configuration
+
+Existing user-facing APIs have not changed, but we suggest moving over to the [`AssetsFinder`](api/scala/controllers/AssetsFinder.html) API for finding assets and setting up your assets directories in configuration:
+
+```
+play.assets {
+ path = "/public"
+ urlPrefix = "/assets"
+}
+```
+
+Then in routes you can do:
+
+```
+# prefix must match `play.assets.urlPrefix`
+GET /assets/*file controllers.Assets.at(file)
+GET /versionedAssets/*file controllers.Assets.versioned(file)
+```
+
+You no longer need to provide an assets path at the start of the argument list, since that's now read from configuration.
+
+Then in your template you can use [`AssetsFinder#path`](api/scala/controllers/AssetsFinder.html#path\(rawPath:String\):String) to find the final path of the asset:
+
+```scala
+@(assets: AssetsFinder)
+
+
+```
+
+You can still continue to use reverse routes with `Assets.versioned`, but some global state is required to convert the asset name you provide to the final asset name, which can be problematic if you want to run multiple applications at once.
+
+## Form changes
+
+Starting with Play 2.6, query string parameters will not be bound to a form instance anymore when using [`bindFromRequest()`](api/scala/play/api/data/Form.html#bindFromRequest\(\)\(implicitrequest:play.api.mvc.Request[_]\):play.api.data.Form[T]) in combination with `POST`, `PUT` or `PATCH` requests.
+
+Static methods which were already deprecated in 2.5 (e.g. `DynamicForm.form()`) were removed in this release. Refer to the [[Play 2.5 Migration Guide|Migration25]] for details on how to migrate, in case you still use them.
+
+### Java Form Changes
+
+The [`errors()`](api/java/play/data/Form.html#errors--) method of a [`play.data.Form`](api/java/play/data/Form.html) instance is now deprecated. You should use `allErrors()` instead now which returns a simple `List` instead of a `Map>`. Where before Play 2.6 you called `.errors().get("key")` you can now simply call `.errors("key")`.
+
+From now on, a `validate` method implemented inside a form class (usually used for cross field validation) is part of a class-level constraint. Check out the [[Advanced validation|JavaForms#advanced-validation]] docs for further information on how to use such constraints.
+Existing `validate` methods can easily be migrated by annotating the affected form classes with `@Validate` and, depending on the return type of the validate method, by implementing the [`Validatable`](api/java/play/data/validation/Constraints.Validatable.html) interface with the applicable type argument (all defined in [`play.data.validation.Constraints`](api/java/play/data/validation/Constraints.html)):
+
+| **Return type** | **Interface to implement**
+| -----------------------------------------------------------------------------------|-------------------------------------
+| `String` | `Validatable`
+| `ValidationError` | `Validatable`
+| `List` | `Validatable>`
+| `Map>`
(not supported anymore; use `List` instead) | `Validatable>`
+
+For example an existing form like:
+
+```java
+public class MyForm {
+ //...
+ public String validate() {
+ //...
+ }
+}
+```
+
+Has to be changed to:
+
+```java
+import play.data.validation.Constraints.Validate;
+import play.data.validation.Constraints.Validatable;
+
+@Validate
+public class MyForm implements Validatable {
+ //...
+ @Override
+ public String validate() {
+ //...
+ }
+}
+```
+
+> **Be aware**: The "old" `validate` method was invoked only after all other constraints were successful before. By default class-level constraints however are called simultaneously with any other constraint annotations - no matter if they passed or failed. To (also) define an order between the constraints you can now use [[constraint groups|JavaForms#defining-the-order-of-constraint-groups]].
+
+## JPA Migration Notes
+
+See [[JPA migration notes|JPAMigration26]].
+
+## I18n Migration Notes
+
+See [[I18N API Migration|MessagesMigration26]].
+
+## Cache APIs Migration Notes
+
+See [[Cache APIs Migration|CacheMigration26]].
+
+## Java Configuration API Migration Notes
+
+See [[Java Configuration Migration|JavaConfigMigration26]].
+
+## Scala Configuration API
+
+The Scala [`play.api.Configuration`](api/scala/play/api/Configuration.html) API now has new methods that allow loading any type using a [`ConfigLoader`](api/scala/play/api/ConfigLoader.html). These new methods expect configuration keys to exist in the configuration file. For example, the following old code:
+
+```scala
+val myConfig: String = configuration.getString("my.config.key").getOrElse("default")
+```
+should be changed to
+```scala
+val myConfig: String = configuration.get[String]("my.config.key")
+```
+and the value "default" should be set in configuration as `my.config.key = default`.
+
+Alternatively, if custom logic is required in the code to obtain the default value, you can set the default to null in your config file (`my.config.key = null`), and read an `Option[T]`:
+```scala
+val myConfigOption: Option[String] = configuration.get[Option[String]]("my.config.key")
+val myConfig: String = myConfigOption.getOrElse(computeDefaultValue())
+```
+
+Also, there are several methods in the old [`play.api.Configuration`](api/scala/play/api/Configuration.html) that return Java types, like `getBooleanList`. We recommend using the Scala version `get[Seq[Boolean]]` instead if possible. If that is not possible, you can access the `underlying` Config object and call `getBooleanList` from it.
+
+The deprecation messages on the existing methods also explain how to migrate each method. See [[the Scala Configuration docs|ScalaConfig]] for more details on the proper use of [`play.api.Configuration`](api/scala/play/api/Configuration.html).
+
+## Play JSON API changes
+
+### JSON array index lookup
+
+If you are using the Scala play-json API, there was a small change in the way the `JsLookup` implicit class works. For example, if you have code like:
+
+```scala
+val bar = (jsarray(index) \ "bar").as[Bar]
+```
+where `index` is an array index and `jsarray` is a `JsArray`, now you should write:
+```scala
+val bar = (jsarray \ index \ "bar").as[Bar]
+```
+
+This was done to bring the behavior of indexing on `JsArray`s in line with that of other collections in Scala. Now the `jsarray(index)` method will return the value at the index, throwing an exception if it does not exist.
+
+## Removed APIs
+
+### Removed Crypto API
+
+The Crypto API has removed the deprecated classes `play.api.libs.Crypto`, `play.libs.Crypto` and `AESCTRCrypter`. The CSRF references to `Crypto` have been replaced by `CSRFTokenSigner`. The session cookie references to `Crypto` have been replaced with `CookieSigner`. Please see [[CryptoMigration25]] for more information.
+
+### `Akka` deprecated methods removed
+
+The deprecated static methods `play.libs.Akka.system` and `play.api.libs.concurrent.Akka.system` were removed. Use dependency injection to get an instance of `ActorSystem` and access to the actor system.
+
+For Scala:
+
+```scala
+class MyComponent @Inject() (system: ActorSystem) {
+
+}
+```
+
+And for Java:
+
+```java
+public class MyComponent {
+
+ private final ActorSystem system;
+
+ @Inject
+ public MyComponent(ActorSystem system) {
+ this.system = system;
+ }
+}
+```
+
+Also, Play 2.6.x now uses the Akka 2.5.x release series. Read Akka [migration guide from 2.4.x to 2.5.x](https://doc.akka.io/docs/akka/current/project/migration-guide-2.4.x-2.5.x.html?language=scala) to see how to adapt your own code if necessary.
+
+### Removed Yaml API
+
+We removed `play.libs.Yaml` since there was no use of it inside of play anymore. If you still need support for the Play YAML integration you need to add `snakeyaml` in you `build.sbt`:
+
+```scala
+libraryDependencies += "org.yaml" % "snakeyaml" % "1.17"
+```
+
+And create the following Wrapper in your Code:
+
+```java
+public class Yaml {
+
+ private final play.Environment environment;
+
+ @Inject
+ public Yaml(play.Environment environment) {
+ this.environment = environment;
+ }
+
+ /**
+ * Load a Yaml file from the classpath.
+ */
+ public Object load(String resourceName) {
+ return load(
+ environment.resourceAsStream(resourceName),
+ environment.classLoader()
+ );
+ }
+
+ /**
+ * Load the specified InputStream as Yaml.
+ *
+ * @param classloader The classloader to use to instantiate Java objects.
+ */
+ public Object load(InputStream is, ClassLoader classloader) {
+ org.yaml.snakeyaml.Yaml yaml = new org.yaml.snakeyaml.Yaml(new CustomClassLoaderConstructor(classloader));
+ return yaml.load(is);
+ }
+
+}
+```
+
+Or in Scala:
+
+```scala
+class Yaml @Inject()(environment: play.api.Environment) {
+ def load(resourceName: String) = {
+ load(environment.resourceAsStream(resourceName), environment.classLoader)
+ }
+
+ def load(inputStream: InputStream, classLoader: ClassLoader) = {
+ new org.yaml.snakeyaml.Yaml(new CustomClassLoaderConstructor(classloader)).load(inputStream)
+ }
+}
+```
+
+If you explicitly depend on an alternate DI library for Play, or have defined your own custom application loader, no changes should be required.
+
+Libraries that provide Play DI support should define the `play.application.loader` configuration key. If no external DI library is provided, Play will refuse to start unless you point that to an [`ApplicationLoader`](api/scala/play/api/ApplicationLoader.html).
+
+### Removed deprecated `play.Routes`
+
+The deprecated `play.Routes` class used to create a JavaScript router were removed. You now have to use the new Java or Scala helpers:
+
+* [[Javascript Routing in Scala|ScalaJavascriptRouting]]
+* [[Javascript Routing in Java|JavaJavascriptRouter]]
+
+## Removed libraries
+
+In order to make the default play distribution a bit smaller we removed some libraries. The following libraries are no longer dependencies in Play 2.6, so you will need to manually add them to your build if you use them.
+
+### Joda-Time removal
+
+We recommend using the `java.time` APIs, so we are removing joda-time support from the core of Play.
+
+Play's Scala forms library had some Joda formats. If you don't wish to migrate, you can add the `jodaForms` module in your `build.sbt`:
+
+```scala
+libraryDependencies += jodaForms
+```
+
+And then import the corresponding object:
+
+```scala
+import play.api.data.JodaForms._
+```
+
+If you need Joda support in play-json, you can add the following dependency:
+
+```scala
+libraryDependencies += "com.typesafe.play" %% "play-json-joda" % playJsonVersion
+```
+
+where `playJsonVersion` is the play-json version you wish to use. Play 2.6.x should be compatible with play-json 2.6.x. Note that play-json is now a separate project (described later).
+
+```scala
+import play.api.libs.json.JodaWrites._
+import play.api.libs.json.JodaReads._
+```
+
+### Joda-Convert removal
+
+Play had some internal uses of `joda-convert` if you used it in your project you need to add it to your `build.sbt`:
+
+```scala
+libraryDependencies += "org.joda" % "joda-convert" % "1.8.1"
+```
+
+### XercesImpl removal
+
+For XML handling Play used the Xerces XML Library. Since modern JVM are using Xerces as a reference implementation we removed it. If your project relies on the external package you can simply add it to your `build.sbt`:
+
+```scala
+libraryDependencies += "xerces" % "xercesImpl" % "2.11.0"
+```
+
+### H2 removal
+
+Prior versions of Play prepackaged the H2 database. But to make the core of Play smaller we removed it. If you make use of H2 you can add it to your `build.sbt`:
+
+```scala
+libraryDependencies += "com.h2database" % "h2" % "1.4.193"
+```
+
+If you only used it in your test you can also just use the `Test` scope:
+
+```scala
+libraryDependencies += "com.h2database" % "h2" % "1.4.193" % Test
+```
+
+The [[H2 Browser|Developing-with-the-H2-Database#H2-Browser]] will still work after you added the dependency.
+
+### snakeyaml removal
+
+Play removed `play.libs.Yaml` and therefore the dependency on `snakeyaml` was dropped. If you still use it add it to your `build.sbt`:
+
+```scala
+libraryDependencies += "org.yaml" % "snakeyaml" % "1.17"
+```
+
+See also [notes about the removal of Yaml API](#Removed-Yaml-API).
+
+### Tomcat-servlet-api removal
+
+Play removed the `tomcat-servlet-api` since it was of no use. If you still use it add it to your `build.sbt`:
+
+```scala
+libraryDependencies += "org.apache.tomcat" % "tomcat-servlet-api" % "8.0.33"
+```
+
+### fork-run removal
+
+The `sbt-fork-run-plugin` will no longer be generated, as it was only needed for the now end-of-life activator utility. As it will no longer resolve for 2.6 it can safely be removed altogether.
+
+## Request attributes
+
+All request objects now contain *attributes*. Request attributes are a replacement for request *tags*. Tags have now been deprecated and you should upgrade to attributes. Attributes are more powerful than tags; you can use attributes to store objects in requests, whereas tags only supported storing Strings.
+
+### Request tags deprecation
+
+Tags have been deprecated so you should start migrating from using tags to using attributes. Migration should be fairly straightforward.
+
+The easiest migration path is to migrate from a tag to an attribute with a `String` type.
+
+Java before:
+
+```java
+// Getting a tag from a Request or RequestHeader
+String userName = req.tags().get("userName");
+// Setting a tag on a Request or RequestHeader
+req.tags().put("userName", newName);
+// Setting a tag with a RequestBuilder
+Request builtReq = requestBuilder.tag("userName", newName).build();
+```
+
+Java after:
+
+```java
+class Attrs {
+ public static final TypedKey USER_NAME = TypedKey.create("userName");
+}
+
+// Getting an attribute from a Request or RequestHeader
+String userName = req.attrs().get(Attrs.USER_NAME);
+String userName = req.attrs().getOptional(Attrs.USER_NAME);
+// Setting an attribute on a Request or RequestHeader
+Request newReq = req.withTags(req.tags().put(Attrs.USER_NAME, newName));
+// Setting an attribute with a RequestBuilder
+Request builtReq = requestBuilder.attr(Attrs.USER_NAME, newName).build();
+```
+
+Scala before:
+
+```scala
+// Getting a tag from a Request or RequestHeader
+val userName: String = req.tags("userName")
+val optUserName: Option[String] = req.tags.get("userName")
+// Setting a tag on a Request or RequestHeader
+val newReq = req.copy(tags = req.tags.updated("userName", newName))
+```
+
+Scala after:
+
+```scala
+object Attrs {
+ val UserName: TypedKey[String] = TypedKey("userName")
+}
+// Getting an attribute from a Request or RequestHeader
+val userName: String = req.attrs(Attrs.UserName)
+val optUserName: [String] = req.attrs.get(Attrs.UserName)
+// Setting an attribute on a Request or RequestHeader
+val newReq = req.addAttr(Attrs.UserName, newName)
+```
+
+However, if appropriate, we recommend you convert your `String` tags into attributes with non-`String` values. Converting your tags into non-`String` objects has several benefits. First, you will make your code more type-safe. This will increase your code's reliability and make it easier to understand. Second, the objects you store in attributes can contain multiple properties, allowing you to aggregate multiple tags into a single value. Third, converting tags into attributes means you don't need to encode and decode values from `String`s, which may increase performance.
+
+```java
+class Attrs {
+ public static final TypedKey USER = TypedKey.create("user");
+}
+```
+
+Scala after:
+
+```scala
+object Attrs {
+ val UserName: TypedKey[User] = TypedKey("user")
+}
+```
+
+### Calling `FakeRequest.withCookies` no longer updates the `Cookies` header
+
+Request cookies are now stored in a request attribute. Previously they were stored in the request's [`Cookie`](api/scala/play/api/mvc/Cookie.html) header `String`. This required encoding and decoding the cookie to the header whenever the cookie changed.
+
+Now that cookies are stored in request attributes updating the cookie will change the new cookie attribute but not the [`Cookie`](api/scala/play/api/mvc/Cookie.html) HTTP header. This will only affect your tests if you're relying on the fact that calling `withCookies` will update the header.
+
+If you still need the old behavior you can still use [`Cookies.encodeCookieHeader`](api/scala/play/api/mvc/Cookies$.html#encodeCookieHeader\(cookies:Seq[play.api.mvc.Cookie]\):String) to convert the [`Cookie`](api/scala/play/api/mvc/Cookie.html) objects into an HTTP header then store the header with `FakeRequest.withHeaders`.
+
+### `play.api.mvc.Security.username` (Scala API), `session.username` changes
+
+`play.api.mvc.Security.username` (Scala API), `session.username` config key and dependent actions helpers are deprecated. `Security.username` just retrieves the `session.username` key from configuration, which defined the session key used to get the username. It was removed since it required statics to work, and it's fairly easy to implement the same or similar behavior yourself.
+
+You can read the username session key from configuration yourself using `configuration.get[String]("session.username")`.
+
+If you're using the `Authenticated(String => EssentialAction)` method, you can easily create your own action to do something similar:
+
+```scala
+def AuthenticatedWithUsername(action: String => EssentialAction) =
+ WithAuthentication[String](_.session.get(UsernameKey))(action)
+```
+
+where `UsernameKey` represents the session key you want to use for the username.
+
+### Request Security (Java API) username property is now an attribute
+
+The Java Request object contains a `username` property which is set when the `Security.Authenticated` annotation is added to a Java action. In Play 2.6 the username property has been deprecated. The username property methods have been updated to store the username in the `Security.USERNAME` attribute. You should update your code to use the `Security.USERNAME` attribute directly. In a future version of Play we will remove the username property.
+
+The reason for this change is that the username property was provided as a special case for the `Security.Authenticated` annotation. Now that we have attributes we don't need a special case anymore.
+
+Existing Java code:
+
+```java
+// Set the username
+Request reqWithUsername = req.withUsername("admin");
+// Get the username
+String username = req1.username();
+// Set the username with a builder
+Request reqWithUsername = new RequestBuilder().username("admin").build();
+```
+
+Updated Java code:
+
+```java
+import play.mvc.Security.USERNAME;
+
+// Set the username
+Request reqWithUsername = req.withAttr(USERNAME, "admin");
+// Get the username
+String username = req1.attr(USERNAME);
+// Set the username with a builder
+Request reqWithUsername = new RequestBuilder().putAttr(USERNAME, "admin").build();
+```
+
+### Router tags are now attributes
+
+If you used any of the `Router.Tags.*` tags, you should change your code to use the new [`Router.Attrs.HandlerDef`](api/scala/play/api/routing/Router$$Attrs$.html#HandlerDef:play.api.libs.typedmap.TypedKey[play.api.routing.HandlerDef]) (Scala) or [`Router.Attrs.HANDLER_DEF`](api/java/play/routing/Router.Attrs.html#HANDLER_DEF) (Java) attribute instead. The existing tags are still available, but are deprecated and will be removed in a future version of Play.
+
+This new attribute contains a `HandlerDef` object with all the information that is currently in the tags. The current tags all correspond to a field in the `HandlerDef` object:
+
+| Java tag name | Scala tag name | `HandlerDef` method |
+|:----------------------|:--------------------|:--------------------|
+| `ROUTE_PATTERN` | `RoutePattern` | `path` |
+| `ROUTE_VERB` | `RouteVerb` | `verb` |
+| `ROUTE_CONTROLLER` | `RouteController` | `controller` |
+| `ROUTE_ACTION_METHOD` | `RouteActionMethod` | `method` |
+| `ROUTE_COMMENTS` | `RouteComments` | `comments` |
+
+> **Note**: As part of this change the `HandlerDef` object has been moved from the `play.core.routing` internal package into the `play.api.routing` public API package.
+
+## `play.api.libs.concurrent.Execution` is deprecated
+
+The `play.api.libs.concurrent.Execution` class has been deprecated, as it was using global mutable state under the hood to pull the "current" application's ExecutionContext.
+
+If you want to specify the implicit behavior that you had previously, then you should pass in the execution context implicitly in the constructor using [[dependency injection|ScalaDependencyInjection]]:
+
+```scala
+class MyController @Inject()(implicit ec: ExecutionContext) {
+
+}
+```
+
+or from BuiltInComponents if you are using [[compile time dependency injection|ScalaCompileTimeDependencyInjection]]:
+
+```scala
+class MyComponentsFromContext(context: ApplicationLoader.Context)
+ extends BuiltInComponentsFromContext(context) {
+ val myComponent: MyComponent = new MyComponent(executionContext)
+}
+```
+
+However, there are some good reasons why you may not want to import an execution context even in the general case. In the general case, the application's execution context is good for rendering actions, and executing CPU-bound activities that do not involve blocking API calls or I/O activity. If you are calling out to a database, or making network calls, then you may want to define your own custom execution context.
+
+The recommended way to create a custom execution context is through [`CustomExecutionContext`](api/scala/play/api/libs/concurrent/CustomExecutionContext.html), which uses the Akka dispatcher system ([java](https://doc.akka.io/docs/akka/2.5/dispatchers.html?language=java) / [scala](https://doc.akka.io/docs/akka/2.5/dispatchers.html?language=scala)) so that executors can be defined through configuration.
+
+To use your own execution context, extend the [`CustomExecutionContext`](api/scala/play/api/libs/concurrent/CustomExecutionContext.html) abstract class with the full path to the dispatcher in the `application.conf` file:
+
+```scala
+import play.api.libs.concurrent.CustomExecutionContext
+
+class MyExecutionContext @Inject()(actorSystem: ActorSystem)
+ extends CustomExecutionContext(actorSystem, "my.dispatcher.name")
+```
+
+```java
+import play.libs.concurrent.CustomExecutionContext;
+class MyExecutionContext extends CustomExecutionContext {
+ @Inject
+ public MyExecutionContext(ActorSystem actorSystem) {
+ super(actorSystem, "my.dispatcher.name");
+ }
+}
+```
+
+and then inject your custom execution context as appropriate:
+
+```scala
+class MyBlockingRepository @Inject()(implicit myExecutionContext: MyExecutionContext) {
+ // do things with custom execution context
+}
+```
+
+Please see [[ThreadPools]] page for more information on custom thread pool configuration, and [[JavaAsync]] / [[ScalaAsync]] for using `CustomExecutionContext`.
+
+## Changes to play.api.test Helpers
+
+The following deprecated test helpers have been removed in 2.6.x:
+
+* `play.api.test.FakeApplication` has been replaced by [`play.api.inject.guice.GuiceApplicationBuilder`](api/scala/play/api/inject/guice/GuiceApplicationBuilder.html).
+* The `play.api.test.Helpers.route(request)` has been replaced with the `play.api.test.Helpers.routes(app, request)` method.
+* The `play.api.test.Helpers.route(request, body)` has been replaced with the [`play.api.test.Helpers.routes(app, request, body)`](api/scala/play/api/test/Helpers$.html) method.
+
+### Java API
+
+* `play.test.FakeRequest` has been replaced by [`RequestBuilder`](api/java/play/mvc/Http.RequestBuilder.html)
+* `play.test.FakeApplication` has been replaced with `play.inject.guice.GuiceApplicationBuilder`. You can create a new `Application` from [`play.test.Helpers.fakeApplication`](api/java/play/inject/guice/GuiceApplicationBuilder.html).
+* In `play.test.WithApplication`, the deprecated `provideFakeApplication` method has been removed -- the `provideApplication` method should be used.
+
+
+## Changes to Template Helpers
+
+The `requireJs` template helper in [`views/helper/requireJs.scala.html`](https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/views/helper/requireJs.scala.html) used `Play.maybeApplication` to access the configuration.
+
+The `requireJs` template helper has an extra parameter `isProd` added to it that indicates whether the minified version of the helper should be used:
+
+```
+@requireJs(core = routes.Assets.at("javascripts/require.js").url, module = routes.Assets.at("javascripts/main").url, isProd = true)
+```
+
+## Changes to File Extension to MIME Type Mapping
+
+The mapping of file extensions to MIME types has been moved to `reference.conf` so it is covered entirely through configuration, under `play.http.fileMimeTypes` setting. Previously the list was hardcoded under `play.api.libs.MimeTypes`.
+
+Note that `play.http.fileMimeTypes` configuration setting is defined using triple quotes as a single string -- this is because several file extensions have syntax that breaks HOCON, such as `c++`.
+
+To append a custom MIME type, use [HOCON string value concatenation](https://github.com/typesafehub/config/blob/master/HOCON.md#string-value-concatenation):
+
+```
+play.http.fileMimeTypes = ${play.http.fileMimeTypes} """
+ foo=text/bar
+"""
+```
+
+There is a syntax that allows configurations defined as `mimetype.foo=text/bar` for additional MIME types. This is deprecated, and you are encouraged to use the above configuration.
+
+### Java API
+
+There is a `Http.Context.current().fileMimeTypes()` method that is provided under the hood to `Results.sendFile` and other methods that look up content types from file extensions. No migration is necessary.
+
+### Scala API
+
+The `play.api.libs.MimeTypes` class has been changed to [`play.api.http.FileMimeTypes`](api/scala/play/api/http/FileMimeTypes.html) interface, and the implementation has changed to [`play.api.http.DefaultFileMimeTypes`](api/scala/play/api/http/DefaultFileMimeTypes.html).
+
+All the results that send files or resources now take `FileMimeTypes` implicitly, i.e.
+
+```scala
+implicit val fileMimeTypes: FileMimeTypes = ...
+Ok(file) // <-- takes implicit FileMimeTypes
+```
+
+An implicit instance of `FileMimeTypes` is provided by `BaseController` (and its subclass `AbstractController` and subtrait `InjectedController`) through the `ControllerComponents` class, to provide a convenient binding:
+
+```scala
+class SendFileController @Inject() (cc: ControllerComponents) extends AbstractController(cc) {
+
+ def index() = Action { implicit request =>
+ val file = readFile()
+ Ok(file) // <-- takes implicit FileMimeTypes
+ }
+}
+```
+
+You can also get a fully configured `FileMimeTypes` instance directly in a unit test:
+
+```scala
+val httpConfiguration = new HttpConfigurationProvider(Configuration.load(Environment.simple)).get
+val fileMimeTypes = new DefaultFileMimeTypesProvider(httpConfiguration.fileMimeTypes).get
+```
+
+Or get a custom one:
+
+```scala
+val fileMimeTypes = new DefaultFileMimeTypesProvider(FileMimeTypesConfiguration(Map("foo" -> "text/bar"))).get
+```
+
+## Default Filters
+
+Play now comes with a default set of enabled filters, defined through configuration. If the property `play.http.filters` is null, then the default is now [`play.api.http.EnabledFilters`](api/scala/play/api/http/EnabledFilters.html), which loads up the filters defined by fully qualified class name in the `play.filters.enabled` configuration property.
+
+In Play itself, `play.filters.enabled` is an empty list. However, the filters library is automatically loaded in sbt as an AutoPlugin called `PlayFilters`, and will append the following values to the `play.filters.enabled` property:
+
+* [`play.filters.csrf.CSRFFilter`](api/scala/play/filters/csrf/CSRFFilter.html)
+* [`play.filters.headers.SecurityHeadersFilter`](api/scala/play/filters/headers/SecurityHeadersFilter.html)
+* [`play.filters.hosts.AllowedHostsFilter`](api/scala/play/filters/hosts/AllowedHostsFilter.html)
+
+This means that on new projects, CSRF protection ([[ScalaCsrf]] / [[JavaCsrf]]), [[SecurityHeaders]] and [[AllowedHostsFilter]] are all defined automatically.
+
+### Effects of Default Filters
+
+The default filters are configured to give a "secure by default" configuration to projects.
+
+**You should keep these filters enabled: they make your application more secure.**
+
+If you did not have these filters enabled in an existing project, then there is some configuration required, and you may not be familiar with the errors and failures involved. To help with migration, we'll go over each filter, what it does and what configuration is required.
+
+#### CSRFFilter
+
+The CSRF filter is described in [[ScalaCsrf]] and [[JavaCsrf]]. It protects against [cross site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery) attacks, by adding a CSRF token to forms that is checked on POST requests.
+
+##### Why it is enabled by default
+
+CSRF is a very common attack that takes very little skill to implement. You can see an example of a CSRF attack using Play at [https://github.com/Manc/play-scala-csrf](https://github.com/Manc/play-scala-csrf).
+
+##### What changes do I need to make?
+
+If you are migrating from an existing project that does not use CSRF form helpers such as `CSRF.formField`, then you may see "403 Forbidden" on PUT and POST requests from the CSRF filter.
+
+Adding `CSRF.formField` to your form templates will resolve the error If you are making requests with AJAX, you can place the CSRF token in the HTML page, and then add it to the request using the `Csrf-Token` header.
+
+To check this behavior, please add `` to your `logback.xml`.
+
+You may also want to enable SameSite cookies in Play, which provide an additional defense against CSRF attacks.
+
+#### SecurityHeadersFilter
+
+[[SecurityHeadersFilter|SecurityHeaders]] prevents [cross site scripting](https://en.wikipedia.org/wiki/Cross-site_scripting) and [clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks, by adding extra HTTP headers to the request.
+
+##### Why it is enabled by default
+
+Browser based attacks are extremely common, and security headers can provide a defense in depth to help frustrate those attacks.
+
+##### What changes do I need to make?
+
+The default "Content-Security-Policy" settings are quite strict, and it is likely that you will need to experiment with it to find the most useful settings. The Content-Security-Policy settings will change how Javascript and remote frames are displayed in a browser. **Embedded Javascript or CSS will not be loaded in your web page until you modify the Content-Security-Policy header.**
+
+If you are sure that you do not want to enable it, you can disable the Content-Security-Policy as follows:
+
+```
+play.filters.headers.contentSecurityPolicy=null
+```
+
+[CSP-Useful](https://github.com/nico3333fr/CSP-useful) is a good resource on Content-Security-Policy in general. Note that there are other potential solutions to embedded Javascript, such as adding a custom CSP nonce on every request.
+
+The other headers are less intrusive, and are unlikely to cause problems on a plain website, but may cause cookie or rendering problems on a Single Page Application. Mozilla has documentation describing each header in detail, using the header name in the URL: for example, for X-Frame-Options go to [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options).
+
+
+```
+play.filters.headers {
+
+ # The X-Frame-Options header. If null, the header is not set.
+ frameOptions = "DENY"
+
+ # The X-XSS-Protection header. If null, the header is not set.
+ xssProtection = "1; mode=block"
+
+ # The X-Content-Type-Options header. If null, the header is not set.
+ contentTypeOptions = "nosniff"
+
+ # The X-Permitted-Cross-Domain-Policies header. If null, the header is not set.
+ permittedCrossDomainPolicies = "master-only"
+
+ # The Content-Security-Policy header. If null, the header is not set.
+ contentSecurityPolicy = "default-src 'self'"
+
+ # The Referrer-Policy header. If null, the header is not set.
+ referrerPolicy = "origin-when-cross-origin, strict-origin-when-cross-origin"
+
+ # If true, allow an action to use .withHeaders to replace one or more of the above headers
+ allowActionSpecificHeaders = false
+}
+```
+
+#### AllowedHostsFilter
+
+The AllowedHostsFilter adds a whitelist of allowed hosts and sends a 400 (Bad Request) response to all requests with a host that do not match the whitelist.
+
+##### Why it is enabled by default
+
+This is an important filter to use in development, because DNS rebinding attacks can be used against a developer’s instance of Play: see [Rails Webconsole DNS Rebinding](https://benmmurphy.github.io/blog/2016/07/11/rails-webconsole-dns-rebinding/) for an example of how short lived DNS rebinding can attack a server running on localhost.
+
+##### What changes do I need to make?
+
+If you are running a Play application on something other than localhost, you must configure the AllowedHostsFilter to specifically allow the hostname/ip you are connecting from. This is especially important to note when you change environments, because typically you'll run on localhost in development, but will run remotely in staging and production.
+
+```
+play.filters.hosts {
+ # Allow requests to example.com, its subdomains, and localhost:9000.
+ allowed = [".example.com", "localhost:9000"]
+}
+```
+
+### Appending To Filters
+
+To append to the defaults list, use the `+=`:
+
+```
+play.filters.enabled+=MyFilter
+```
+
+If you have defined your own filters by extending `play.api.http.DefaultHttpFilters`, then you can also combine `EnabledFilters` with your own list in code, so if you have previously defined projects, they still work as usual:
+
+```scala
+class Filters @Inject()(enabledFilters: EnabledFilters, corsFilter: CORSFilter)
+ extends DefaultHttpFilters(enabledFilters.filters :+ corsFilter: _*)
+```
+
+### Testing Default Filters
+
+Because there are several filters enabled, functional tests may need to change slightly to ensure that all the tests pass and requests are valid. For example, a request that does not have a `Host` HTTP header set to `localhost` will not pass the AllowedHostsFilter and will return a 400 Forbidden response instead.
+
+#### Testing with AllowedHostsFilter
+
+Because the AllowedHostsFilter filter is added automatically, functional tests need to have the Host HTTP header added.
+
+If you are using `FakeRequest` or `Helpers.fakeRequest`, then the `Host` HTTP header is added for you automatically. If you are using `play.mvc.Http.RequestBuilder`, then you may need to add your own line to add the header manually:
+
+```java
+RequestBuilder request = new RequestBuilder()
+ .method(GET)
+ .header(HeaderNames.HOST, "localhost")
+ .uri("/xx/Kiwi");
+```
+
+#### Testing with CSRFFilter
+
+Because the CSRFFilter filter is added automatically, tests that render a Twirl template that includes `CSRF.formField`, i.e.
+
+```scala
+@(userForm: Form[UserData])(implicit request: RequestHeader, m: Messages)
+
+user form
+
+@request.flash.get("success").getOrElse("")
+
+@helper.form(action = routes.UserController.userPost()) {
+ @helper.CSRF.formField
+ @helper.inputText(userForm("name"))
+ @helper.inputText(userForm("age"))
+
+}
+```
+
+must contain a CSRF token in the request. In the Scala API, this is done by importing `play.api.test.CSRFTokenHelper._`, which enriches `play.api.test.FakeRequest` with the `withCSRFToken` method:
+
+```scala
+import play.api.test.CSRFTokenHelper._
+
+class UserControllerSpec extends PlaySpec with GuiceOneAppPerTest {
+ "UserController GET" should {
+
+ "render the index page from the application" in {
+ val controller = app.injector.instanceOf[UserController]
+ val request = FakeRequest().withCSRFToken
+ val result = controller.userGet().apply(request)
+
+ status(result) mustBe OK
+ contentType(result) mustBe Some("text/html")
+ }
+ }
+}
+```
+
+In the Java API, this is done by calling `CSRFTokenHelper.addCSRFToken` on a `play.mvc.Http.RequestBuilder` instance:
+
+```
+requestBuilder = CSRFTokenHelper.addCSRFToken(requestBuilder);
+```
+
+### Disabling Default Filters
+
+The simplest way to disable the default filters is to set the list of filters manually in `application.conf`:
+
+```
+play.filters.enabled=[]
+```
+
+This may be useful if you have functional tests that you do not want to go through the default filters.
+
+If you want to remove all filter classes, you can disable it through the `disablePlugins` mechanism:
+
+```
+lazy val root = project.in(file(".")).enablePlugins(PlayScala).disablePlugins(PlayFilters)
+```
+
+or by replacing `EnabledFilters`:
+
+```
+play.http.filters=play.api.http.NoHttpFilters
+```
+
+If you are writing functional tests involving `GuiceApplicationBuilder` and you want to disable default filters, then you can disable all or some of the filters through configuration by using `configure`:
+
+```scala
+GuiceApplicationBuilder().configure("play.http.filters" -> "play.api.http.NoHttpFilters")
+```
+
+## Compile Time Default Filters
+
+If you are using compile time dependency injection, then the default filters are resolved at compile time, rather than through runtime.
+
+This means that the `BuiltInComponents` trait now contains an `httpFilters` method which is left abstract:
+
+```scala
+trait BuiltInComponents {
+
+ /** A user defined list of filters that is appended to the default filters */
+ def httpFilters: Seq[EssentialFilter]
+}
+```
+
+The default list of filters is defined in `play.filters.HttpFiltersComponents`:
+
+```scala
+trait HttpFiltersComponents
+ extends CSRFComponents
+ with SecurityHeadersComponents
+ with AllowedHostsComponents {
+
+ def httpFilters: Seq[EssentialFilter] = Seq(csrfFilter, securityHeadersFilter, allowedHostsFilter)
+}
+```
+
+In most cases you will want to mixin HttpFiltersComponents and append your own filters:
+
+```scala
+class MyComponents(context: ApplicationLoader.Context)
+ extends BuiltInComponentsFromContext(context)
+ with play.filters.HttpFiltersComponents {
+
+ lazy val loggingFilter = new LoggingFilter()
+ override def httpFilters = {
+ super.httpFilters :+ loggingFilter
+ }
+}
+```
+
+If you want to filter elements out of the list, you can do the following:
+
+```scala
+class MyComponents(context: ApplicationLoader.Context)
+ extends BuiltInComponentsFromContext(context)
+ with play.filters.HttpFiltersComponents {
+ override def httpFilters = {
+ super.httpFilters.filterNot(_.getClass == classOf[CSRFFilter])
+ }
+}
+```
+
+### Disabling Compile Time Default Filters
+
+To disable the default filters, mixin `play.api.NoHttpFiltersComponents`:
+
+```scala
+class MyComponents(context: ApplicationLoader.Context)
+ extends BuiltInComponentsFromContext(context)
+ with NoHttpFiltersComponents
+ with AssetsComponents {
+
+ lazy val homeController = new HomeController(controllerComponents)
+ lazy val router = new Routes(httpErrorHandler, homeController, assets)
+}
+```
+
+## JWT Support
+
+Play's cookie encoding has been switched to use JSON Web Token (JWT) under the hood. JWT comes with a number of advantages, notably automatic signing with HMAC-SHA-256, and support for automatic "not before" and "expires after" date checks which ensure the session cookie cannot be reused outside of a given time window.
+
+More information is available under [[Configuring the Session Cookie|SettingsSession]] page.
+
+### Fallback Cookie Support
+
+Play's cookie encoding uses a "fallback" cookie encoding mechanism that reads in JWT encoded cookies, then attempts reading a URL encoded cookie if the JWT parsing fails, so you can safely migrate existing session cookies to JWT. This functionality is in the `FallbackCookieDataCodec` trait and leveraged by `DefaultSessionCookieBaker` and `DefaultFlashCookieBaker`.
+
+### Legacy Support
+
+Using JWT encoded cookies should be seamless, but if you want, you can revert back to URL encoded cookie encoding by switching to `play.api.mvc.LegacyCookiesModule` in application.conf file:
+
+```
+play.modules.disabled+="play.api.mvc.CookiesModule"
+play.modules.enabled+="play.api.mvc.LegacyCookiesModule"
+```
+
+### Custom CookieBakers
+
+If you have custom cookies being used in Play, using the `CookieBaker[T]` trait, then you will need to specify what kind of encoding you want for your custom cookie baker.
+
+The `encode` and `decode` methods that `Map[String, String]` to and from the format found in the browser have been extracted into `CookieDataCodec`. There are three implementations: `FallbackCookieDataCodec`, `JWTCookieDataCodec`, or `UrlEncodedCookieDataCodec`, which respectively represent URL-encoded with an HMAC, or a JWT, or a "read signed or JWT, write JWT" codec.
+
+You will also need to provide a `JWTConfiguration` case class, using the `JWTConfigurationParser` with the path to your configuration, or use `JWTConfiguration()` for the defaults.
+
+
+```scala
+@Singleton
+class UserInfoCookieBaker @Inject()(service: UserInfoService,
+ val secretConfiguration: SecretConfiguration)
+ extends CookieBaker[UserInfo] with JWTCookieDataCodec {
+
+ override val COOKIE_NAME: String = "userInfo"
+
+ override val isSigned = true
+
+ override def emptyCookie: UserInfo = new UserInfo()
+
+ override protected def serialize(userInfo: UserInfo): Map[String, String] = service.encrypt(userInfo)
+
+ override protected def deserialize(data: Map[String, String]): UserInfo = service.decrypt(data)
+
+ override val path: String = "/"
+
+ override val jwtConfiguration: JWTConfiguration = JWTConfigurationParser()
+}
+```
+
+## Deprecated Futures methods
+
+The following `play.libs.concurrent.Futures` static methods have been deprecated:
+
+* `timeout(A value, long amount, TimeUnit unit)`
+* `timeout(final long delay, final TimeUnit unit)`
+* `delayed(Supplier supplier, long delay, TimeUnit unit, Executor executor)`
+
+A dependency injected instance of `Futures` should be used instead:
+
+```java
+class MyClass {
+ @Inject
+ public MyClass(play.libs.concurrent.Futures futures) {
+ this.futures = futures;
+ }
+
+ CompletionStage callWithOneSecondTimeout() {
+ return futures.timeout(computePIAsynchronously(), Duration.ofSeconds(1));
+ }
+}
+```
+
+## Updated libraries
+
+### Netty 4.1
+
+Netty was upgraded to [version 4.1](https://netty.io/news/2016/05/26/4-1-0-Final.html). This was possible mainly because version 4.0 was shaded by [[play-ws migration to a standalone module|WSMigration26]]. So, if you are using [[Netty Server|NettyServer]] and some library that depends on Netty 4.0, we recommend that you try to upgrade to a newer version of the library, or you can start to use the [[Akka Server|AkkaHttpServer]].
+
+And if you are, for some reason, directly using Netty classes, you should [adapt your code to this new version](https://netty.io/wiki/new-and-noteworthy-in-4.1.html).
+
+### FluentLenium and Selenium
+
+The FluentLenium library was updated to version 3.2.0 and Selenium was updated to version [3.3.1](https://seleniumhq.wordpress.com/2016/10/13/selenium-3-0-out-now/) (you may want to see the [changelog here](https://raw.githubusercontent.com/SeleniumHQ/selenium/master/java/CHANGELOG)). If you were using Selenium's WebDriver API before, there should not be anything to do. Please check [this](https://seleniumhq.wordpress.com/2016/10/04/selenium-3-is-coming/) announcement for further information.
+If you were using the FluentLenium library you might have to change some syntax to get your tests working again. Please see FluentLenium's [Migration Guide](http://fluentlenium.org/migration/from-0.13.2-to-1.0-or-3.0/) for more details about how to adapt your code.
+
+### HikariCP
+
+HikariCP was updated and a new configuration was introduced: `initializationFailTimeout`. This new configuration should be used to replace `initializationFailFast` which is now deprecated. See [HikariCP changelog](https://github.com/brettwooldridge/HikariCP/blob/dev/CHANGES) and [documentation for `initializationFailTimeout`](https://github.com/brettwooldridge/HikariCP#infrequently-used) to better understand how to use this new configuration.
+
+## Other Configuration changes
+
+There are some configuration changes. The old configuration paths will generally still work, but a deprecation warning will be output at runtime if you use them. Here is a summary of the changed keys:
+
+| Old key | New key |
+|-------------------------------|-----------------------------------------|
+| `play.crypto.secret` | `play.http.secret.key` |
+| `play.crypto.provider` | `play.http.secret.provider` |
+| `play.websocket.buffer.limit` | `play.server.websocket.frame.maxLength` |
diff --git a/manual/releases/release26/migration26/WSMigration26.md b/manual/releases/release26/migration26/WSMigration26.md
new file mode 100644
index 00000000..049b165f
--- /dev/null
+++ b/manual/releases/release26/migration26/WSMigration26.md
@@ -0,0 +1,117 @@
+
+# Play WS Migration Guide
+
+Play WS now has a standalone version - [https://github.com/playframework/play-ws](https://github.com/playframework/play-ws) - that can be used outside a Play project. If you have a Play sbt project, you can still add WS by adding the following line to your `build.sbt`:
+
+```scala
+libraryDependencies += ws
+```
+
+This includes the `play-ahc-ws` module, which wraps the standalone version with Play Dependency Injection bindings and components, configuration and anything else that is necessary to better integrate it.
+
+
+And if you want to use the cache support, you need to add `ws`, `ehcache` and [[enable and configure cache|WsCache]]:
+
+```scala
+libraryDependencies += ws
+libraryDependencies += ehcache
+```
+
+If you want to use it in a non Play project, it can be added to an sbt project with:
+
+```scala
+libraryDependencies += "com.typesafe.play" %% "play-ahc-ws-standalone" % "1.1.2"
+libraryDependencies += "com.typesafe.play" %% "play-ws-standalone-json" % "1.1.2"
+libraryDependencies += "com.typesafe.play" %% "play-ws-standalone-xml" % "1.1.2"
+```
+
+## Package changes
+
+Play WS historically consisted of two libraries, `ws` and `playWs`, containing the Scala and Java APIs respectively, each individually creating an AsyncHTTPClient behind the scenes. There is now only one `play-ahc-ws` library, which contains both Scala and Java `WSClient` instances, and both point to a singleton `AsyncHttpClient` provider.
+
+## Project changes
+
+Play WS now exists as a Play specific wrapper on top of a standalone WS library, which does not depend on Play classes, and which uses package renamed "shaded" versions of AsyncHttpClient, Signpost, and Netty 4.0.
+
+By providing a standalone WS version and using shaded libraries, WS is more flexible and has fewer collisions with other libraries and projects.
+
+The Play WS API extends Standalone WS `post` with `Http.Multipart` and `Multipart` types that are only available in Play, for example:
+
+```scala
+def withBody(body: Source[MultipartFormData.Part[Source[ByteString, _]], _]): Self
+```
+
+Signpost OAuth has been changed so that instead of using the Commons HTTPClient OAuthProvider, it now uses the DefaultOAuthProvider, which uses HTTPURLConnection under the hood.
+
+## API changes
+
+### Scala
+
+The `WSAPI` class has been removed. The `WSClient` interface is the point of entry for the WS API.
+
+`WSRequest` had a `withBody[T](body: T)(implicit writable: play.api.http.Writable[T])` method has been replaced as it was difficult to track the behavior of `Writable`. There is now a custom `BodyWritable[T]` type class that fills the same function, and which has type class instances defined in Standalone WS:
+
+```scala
+override def withBody[T: BodyWritable](body: T)
+```
+
+The deprecated Scala singleton object `play.api.libs.ws.WS` has been removed. An instance of `WSClient` should be used instead. If compile time dependency injection is being used, then the `AhcWSComponents` trait should be mixed in.
+
+For Guice, there is a `WSClient` available in the system:
+
+```scala
+class MyService @Inject()(ws: WSClient) {
+ def call(): Unit = {
+ ws.url("http://localhost:9000/foo").get()
+ }
+}
+```
+
+If you cannot use an injected WSClient instance, then you can also create your [[own instance of WSClient|ScalaWS#using-wsclient]], but you are then responsible for managing the lifecycle of the client.
+
+If you are running a functional test, you can use the `play.api.test.WsTestClient`, which will start up and shut down a standalone WSClient instance:
+
+```scala
+play.api.test.WsTestClient.withClient { ws =>
+ ws.url("http://localhost:9000/foo").get()
+}
+```
+
+The `ning` package has been replaced by the `ahc` package, and the Ning* classes replaced by AHC*.
+
+A normal `WSResponse` instance is returned from `stream()` instead of `StreamedResponse`. You should call `response.bodyAsSource` to return the streamed result.
+
+There are some naming changes with deprecations to make things more explicit on `play.api.libs.ws.WSRequest`. Extra care should be exercised when migrating these:
+- [`WsRequest.withHeaders`](https://playframework.com/documentation/2.6.x/api/scala/index.html#play.api.libs.ws.WSRequest@withHeaders\(headers:\(String,String\)*\):WSRequest.this.Self) is now [`WsRequest.addHttpHeaders`](https://playframework.com/documentation/2.6.x/api/scala/index.html#play.api.libs.ws.WSRequest@addHttpHeaders\(hdrs:\(String,String\)*\):StandaloneWSRequest.this.Self) (same behaviour) or [`WsRequest.withHttpHeaders`](https://playframework.com/documentation/2.6.x/api/scala/index.html#play.api.libs.ws.WSRequest@withHttpHeaders\(headers:\(String,String\)*\):WSRequest.this.Self) (throws away existing headers)
+- [`WsRequest.withQueryString`](https://playframework.com/documentation/2.6.x/api/scala/index.html#play.api.libs.ws.WSRequest@withQueryString\(parameters:\(String,String\)*\):WSRequest.this.Self) is now [`WsRequest.addQueryStringParameters`](https://playframework.com/documentation/2.6.x/api/scala/index.html#play.api.libs.ws.WSRequest@addQueryStringParameters\(parameters:\(String,String\)*\):StandaloneWSRequest.this.Self) (same behaviour) or [`WsRequest.withQueryStringParameters`](https://playframework.com/documentation/2.6.x/api/scala/index.html#play.api.libs.ws.WSRequest@withQueryStringParameters\(parameters:\(String,String\)*\):WSRequest.this.Self) (throws away existing query string)
+
+### Java
+
+In Java, the `play.libs.ws.WS` class has been deprecated. An injected `WSClient` instance should be used instead.
+
+```java
+public class MyService {
+ private final WSClient ws;
+
+ @Inject
+ public MyService(WSClient ws) {
+ this.ws = ws;
+ }
+
+ public void call() {
+ ws.url("http://localhost:9000/foo").get();
+ }
+}
+```
+
+If you cannot use an injected WSClient instance, then you can also create your [[own instance of WSClient|JavaWS#using-wsclient]], but you are then responsible for managing the lifecycle of the client.
+
+If you are running a functional test, you can use the `play.test.WsTestClient`, which will start up and shut down a standalone `WSClient` instance:
+
+```java
+WSClient ws = play.test.WsTestClient.newClient(19001);
+...
+ws.close();
+```
+
+A normal `WSResponse` instance is returned from `stream()` instead of `StreamedResponse`. You should call `response.getBodyAsSource()` to return the streamed result.
diff --git a/manual/releases/release26/migration26/index.toc b/manual/releases/release26/migration26/index.toc
new file mode 100644
index 00000000..136cc2e7
--- /dev/null
+++ b/manual/releases/release26/migration26/index.toc
@@ -0,0 +1,6 @@
+Migration26:Migration Guide
+MessagesMigration26:Messages Migration
+WSMigration26:WS Migration
+CacheMigration26:Cache Migration
+JPAMigration26:JPA Migration
+JavaConfigMigration26: Java Configuration API Migration
\ No newline at end of file
diff --git a/manual/tutorial/HelloWorldTutorial.md b/manual/tutorial/HelloWorldTutorial.md
new file mode 100644
index 00000000..e90908f2
--- /dev/null
+++ b/manual/tutorial/HelloWorldTutorial.md
@@ -0,0 +1,41 @@
+
+
+# Hello World Tutorial
+
+This tutorial describes how Play applications work, and shows you how to create a page that displays a customized Hello World greeting.
+
+You can use any Java build tool to build a Play project. This tutorial demonstrates sbt and Gradle because they both provide the development experience Play is known and loved for, such as auto-reloading, clear error messages, and template compilation. The tutorial procedures assume use of `sbt` or `gradlew` commands from a terminal, but you can also integrate Play projects with your favorite [[IDE]].
+
+## Starting the project
+
+Before following the tutorial instructions:
+
+1. Make sure you have verified the [[requirements for running Play|Requirements]]
+1. Obtain the appropriate example zip file:
+ 1. [Play Java Starter Example](https://developer.lightbend.com/start/?group=play&project=play-java-starter-example)
+ 1. [Play Scala Starter Example](https://developer.lightbend.com/start/?group=play&project=play-scala-starter-example)
+1. Unzip and run the example following the steps in the `README.md` file.
+
+
+> **Note**: When you run the tutorial application, it displays web pages with the same content and instructions contained here in the documentation. The tutorial includes a deliberate mistake and having the documenation and application pages open in different tabs or browsers allows you to consult the documentation for the fix when you encounter the error.
+
+## Introduction to Play
+
+As illustrated below, Play is a full-stack framework with all of the components you need to build a Web Application or a REST service, including: an integrated HTTP server, form handling, Cross-Site Request Forgery (CSRF) protection, a powerful routing mechanism, I18n support, and more. Play integrates with many object relational mapping (ORM) layers. It supports [[Anorm]], [[Ebean|JavaEbean]], [[Slick|PlaySlick]], and [[JPA|JavaJPA]] out-of-the-box, but many customers use NoSQL, other ORMs or even access data from a REST service.
+
+[[images/play-stack.png]]
+
+Play APIs are available in both Java and Scala. The Framework uses [Akka](https://akka.io) and [Akka HTTP](https://doc.akka.io/docs/akka-http/current/index.html) under the hood. This endows Play applications with a stateless, non-blocking, event-driven architecture that provides horizontal and vertical scalability and uses resources more efficiently. Play projects contain Scala components, but because Play has a Java API, Java developers do not need to learn Scala to use Play successfully.
+
+Here are just a few of the reasons developers love using Play Framework:
+
+- Its Model-View-Controller (MVC) architecture is familiar and easy to learn.
+- Direct support of common web development tasks and hot reloading saves precious development time.
+- A large active community promotes knowledge sharing.
+- [Twirl templates](https://github.com/playframework/twirl) render pages. The Twirl template language is:
+ - Easy to learn
+ - Requires no special editor
+ - Provides type safety
+ - Is compiled so that errors display in the browser
+
+To learn more about Play's benefits, see Play's [[Introduction]] and [[Philosophy]]. Now, let's dive into what a Play application looks like.
diff --git a/manual/tutorial/ImplementingHelloWorld.md b/manual/tutorial/ImplementingHelloWorld.md
new file mode 100644
index 00000000..370ba458
--- /dev/null
+++ b/manual/tutorial/ImplementingHelloWorld.md
@@ -0,0 +1,114 @@
+
+
+# Implementing Hello World
+
+To see how simple it is to work with Play, let's add a customized `"Hello World"` greeting to this tutorial app.
+
+The main steps include:
+
+1. Create the Hello World page
+1. Add an action method
+1. Define a route
+1. Customize the greeting
+
+## 1. Create the Hello World page
+
+Follow the instructions below to add a new Hello World page to this project.
+
+With any text editor, create a file named `hello.scala.html` and save it in the `app/views` directory of this project. Add the following contents to the file:
+
+@[hello-world-page](code/javaguide/hello/hello.scala.html)
+
+This Twirl and HTML markup accomplishes the following:
+
+1. The `@` sign tells the template engine to interpret what follows.
+1. In this case, `@main("Hello")` calls the main template, `main.scala.html` and passes it the page title of `"Hello"`.
+1. The content section contains the `Hello World` greeting. The main template will insert this into the body of the page.
+
+Now we are ready to add an action method that will render the new page.
+
+## 2. Add an action method
+
+To add an action method for the new page:
+
+Open the `app/controllers/HomeController.java` (or `.scala`) file. Under the tutorial method and before the closing brace, add the following method:
+
+Java
+:
+@[hello-world-hello-action](code/javaguide/hello/HelloController.java)
+
+Scala
+:
+@[hello-world-hello-action](code/scalaguide/hello/HelloController.scala)
+
+To have Play call the new action method when the browser requests the `hello` page, we need to add a route that maps the page to the method.
+
+## 3. Define a route
+
+To define a route for the new Hello page:
+
+Open the `conf/routes` file and add the following line:
+
+@[hello-world-hello-route](code/routes)
+
+When you add a route to the `routes` file, Play's routes compiler will automatically generate a router class that calls that action using an instance of your controller. For more information see the [routing documentation](https://www.playframework.com/documentation/2.6.x/ScalaRouting#HTTP-routing). By default, the controller instances are created using dependency injection (see docs for [[Java|JavaDependencyInjection]] and [[Scala|ScalaDependencyInjection]]).
+
+You are now ready to test the new page. If you stopped the application for some reason, restart it with the `sbt run` command.
+
+Enter the URL to view the results of your work. The browser should respond with something like the following:
+
+[[images/hello-page.png]]
+
+## 4. Customize the greeting
+
+As the final part of this tutorial, we'll modify the hello page to accept an HTTP request parameter. The steps include a deliberate mistake to demonstrate how Play provides useful feedback.
+
+To customize the Hello World greeting, follow the instructions below.
+
+In the `app/controllers/HomeController.java` (or `.scala`) file, modify the `hello` action method to accept a name parameter using the following code:
+
+Java
+:
+@[hello-world-hello-error-action](code/javaguide/hello/HelloController.java)
+
+Scala
+:
+@[hello-world-hello-error-action](code/scalaguide/hello/HelloController.scala)
+
+In the `conf/routes` file, add a `(name: String)` parameter at the end of the `hello`:
+
+@[hello-world-hello-name-route](code/routes)
+
+In Twirl templates, all variables and their types must be declared. In the `app/views/hello.scala.html` file:
+
+1. Insert a new line at the top of the file.
+1. On that line, add an @ directive that declares the name parameter and its type: `@(name: String)`
+1. To use the variable on the page, change the text in the `` heading from `Hello World!` to `Hello @name!
`.
+
+The end result will be:
+
+@[](code/javaguide/hello/helloName.scala.html)
+
+In the browser, enter the following URL and pass in any name as a query parameter to the hello method: . Play responds with a helpful compilation error that lets you know that the render method in the return value requires a typed parameter:
+
+[[images/hello-error.png]]
+
+To fix the compilation error, modify the `hello` action method in `HomeController` so that the it includes the `name` parameter when rendering the view:
+
+Java
+:
+@[hello-world-hello-correct-action](code/javaguide/hello/HelloController.java)
+
+Scala
+:
+@[hello-world-hello-correct-action](code/scalaguide/hello/HelloController.scala)
+
+Save the file and refresh the browser. The page should display a customized greeting similar to the following:
+
+[[images/hello-name.png]]
+
+## Summary
+
+Thanks for trying our tutorial. You learned how to use an action method, routes, Twirl template, and input parameter to create a customized Hello World greeting! You experienced how template compilation makes it easier to identify and fix problems and how auto-reloading saves time.
+
+This was just a simple example to get you started. Let's now see other official examples and tutorials from the community.
diff --git a/manual/tutorial/PlayApplicationOverview.md b/manual/tutorial/PlayApplicationOverview.md
new file mode 100644
index 00000000..f3858831
--- /dev/null
+++ b/manual/tutorial/PlayApplicationOverview.md
@@ -0,0 +1,51 @@
+
+
+# Play Application Overview
+
+This tutorial is implemented as a simple Play application that we can examine to start learning about Play. Let's first look at what happens at runtime. When you enter in your browser:
+
+1. The browser requests the root `/` URI from the HTTP server using the `GET` method.
+1. The Play internal HTTP Server receives the request.
+1. Play resolves the request using the `routes` file, which maps URIs to controller action methods.
+1. The action method renders the `index` page, using Twirl templates.
+1. The HTTP server returns the response as an HTML page.
+
+At a high level, the flow looks something like this:
+
+[[images/play-request-response.png]]
+
+## Explore the project
+
+Next, let's look at the tutorial project to locate the implementation for:
+
+1. The routes file that maps the request to the controller method.
+1. The controller action method that defines how to handle a request to the root URI.
+1. The Twirl template that the action method calls to render the HTML markup.
+
+Follow these steps to drill down into the source files:
+
+> **Note:** In the following procedures, for Windows shells, use \ in place of / in path names (no need to change URL path names though).
+
+Using a command window or GUI, look at the contents of the top-level project directory. The following directories contain application components:
+
+1. The `app` subdirectory contains directories for `controllers` and `views`, which will be familiar to those experienced with the Model View Controller (MVC) architecture. Since this simple project does not need an external data repository, it does not contain a `models` directory, but this is where you would add it.
+1. The `public` subdirectory contains directories for `images`, `javascripts`, and `stylesheets`.
+1. The `conf` directory contains application configuration. For details on the rest of the project's structure see [[Anatomy of a Play Application|Anatomy]].
+
+To locate the controller action method, open `app/controllers/HomeController.java` (or `.scala`) file with your favorite text editor. The `Homecontroller` class includes the `index` action method, as shown below. This is a very simple action method that generate an HTML page from the `index.scala.html` Twirl template file.
+
+Java
+:
+@[hello-world-index-action](code/javaguide/hello/HelloController.java)
+
+Scala
+:
+@[hello-world-index-action](code/scalaguide/hello/HelloController.scala)
+
+To view the route that maps the browser request to the controller method, open the `conf/routes` file. A route consists of an HTTP method, a path, and an action. This control over the URL schema makes it easy to design clean, human-readable, bookmarkable URLs. The following line maps a GET request for the root URL `/` to the `index` action in `HomeController`:
+
+@[hello-world-index-route](code/routes)
+
+Open `app/views/index.scala.html` with your text editor. The main directive in this file calls the main template `main.scala.html` with the string Welcome to generate the page. You can open `app/views/main.scala.html` to see how a `String` parameter sets the page title.
+
+With this overview of the tutorial application, you are ready to add a "Hello World" greeting.
\ No newline at end of file
diff --git a/manual/tutorial/Tutorials.md b/manual/tutorial/Tutorials.md
new file mode 100644
index 00000000..cbbd862f
--- /dev/null
+++ b/manual/tutorial/Tutorials.md
@@ -0,0 +1,217 @@
+
+# Play Tutorials
+
+Play's documentation shows the available features and how to use them, but the documentation will not show how to create an application from start to finish. This is where tutorials and examples come in.
+
+Tutorials and examples are useful for showing a single application at work, especially when it comes to integrating with other systems such as databases or Javascript frameworks.
+
+The Play team uses [Lightbend Tech Hub](https://developer.lightbend.com/start/?group=play) to publish tutorials that cover a huge number of cases. There you can find projects in Java, Scala and for multiple versions of Play. You can pick one that demonstrates functionality of interest to you. The examples you can download cover the following topics:
+
+### Java
+
+| Example | Repository |
+|:------------------------------------------|:-----------------------------------------------------------------------------------|
+| REST API Example | [GitHub](https://github.com/playframework/play-java-rest-api-example/tree/2.6.x) |
+| File Upload Example | [GitHub](https://github.com/playframework/play-java-fileupload-example/tree/2.6.x) |
+| Forms Example | [GitHub](https://github.com/playframework/play-java-forms-example/tree/2.6.x) |
+| JPA Example | [GitHub](https://github.com/playframework/play-java-jpa-example/tree/2.6.x) |
+| Ebean Example | [GitHub](https://github.com/playframework/play-java-ebean-example/tree/2.6.x) |
+| Websocket Example | [GitHub](https://github.com/playframework/play-java-websocket-example/tree/2.6.x) |
+| Chatroom using Websockets Example | [GitHub](https://github.com/playframework/play-java-chatroom-example/tree/2.6.x) |
+| Streaming Example | [GitHub](https://github.com/playframework/play-java-streaming-example/tree/2.6.x) |
+| Compile Time Dependency Injection Example | [GitHub](https://github.com/playframework/play-java-compile-di-example/tree/2.6.x) |
+| Using Dagger 2 for Compile Time DI | [GitHub](https://github.com/playframework/play-java-dagger2-example/tree/2.6.x) |
+
+### Scala
+
+| Example | Repository |
+|:-------------------------------------------|:--------------------------------------------------------------------------------------------|
+| REST API Example | [GitHub](https://github.com/playframework/play-scala-rest-api-example/tree/2.6.x) |
+| File Upload Example | [GitHub](https://github.com/playframework/play-scala-fileupload-example/tree/2.6.x) |
+| Forms Example | [GitHub](https://github.com/playframework/play-scala-forms-example/tree/2.6.x) |
+| Anorm Example | [GitHub](https://github.com/playframework/play-scala-anorm-example/tree/2.6.x) |
+| Integrated Slick Example | [GitHub](https://github.com/playframework/play-scala-slick-example/tree/2.6.x) |
+| Isolated Slick Example | [GitHub](https://github.com/playframework/play-scala-isolated-slick-example/tree/2.6.x) |
+| Websocket Example | [GitHub](https://github.com/playframework/play-scala-websocket-example/tree/2.6.x) |
+| Chatroom using Websockets Example | [GitHub](https://github.com/playframework/play-scala-chatroom-example/tree/2.6.x) |
+| Streaming Example | [GitHub](https://github.com/playframework/play-scala-streaming-example/tree/2.6.x) |
+| Compile Time Dependency Injection Example | [GitHub](https://github.com/playframework/play-scala-compile-di-example/tree/2.6.x) |
+| Dependency Injection using Macwire Example | [GitHub](https://github.com/playframework/play-scala-macwire-di-example/tree/2.6.x) |
+| Secure Session Example | [GitHub](https://github.com/playframework/play-scala-secure-session-example/tree/2.6.x) |
+
+## Third Party Tutorials and Templates
+
+The Play community also has a number of tutorials and templates that cover aspects of Play than the documentation can, or has a different angle. Templates listed here are not maintained by the Play team, and so may be out of date.
+
+This is an incomplete list of several helpful blog posts, and because some of the blog posts have been written a while ago, this section is organized by Play version.
+
+### 2.6.x
+
+#### Play Framework Tutorials and other contents
+
+* [Running Play on GraalVM](https://blog.playframework.com/play-on-graal/): Play's core contributor Christian Schmitt explains how to run Play applications using [GraalVM](https://www.graalvm.org/) and the challenges and benefits of using GraalVM with Play.
+* [Getting Started With Play Framework](https://dzone.com/refcardz/getting-started-play-framework): This DZone's reference card shows the most basic concepts of Play in a resumed but very informative way.
+* [Play: The Missing Tutorial](https://github.com/shekhargulati/play-the-missing-tutorial/blob/master/01-hello-world.md): In this tutorial series, Shekhar Gulati
+ shows how to build a blogging platform called blogy that you can use to write and publish blogs.
+* [Our adventure using Play Framework with Kotlin](https://blog.karumi.com/our-adventure-using-play-framework-in-kotlin/): This article written by [Antonio López Marín](http://tonilopezmr.github.io/) for [Karumi](https://www.karumi.com/) details the steps necessary to write a Play application using Kotlin language.
+* [Add Authentication to Play Framework with OIDC and Okta](https://developer.okta.com/blog/2017/10/31/add-authentication-to-play-framework-with-oidc): [Matt Raible](https://twitter.com/mraible) shows how easy it is to integrate Play with a modern authentication mechanism like OpenID Connect using [play-pac4j](https://github.com/pac4j/play-pac4j).
+* [REST API using Play Framework with Java](http://softwaredevelopercentral.blogspot.com/2017/10/rest-api-using-play-framework-with-java.html): This article shows how to create an application using Play Framework and Java with `GET`, `POST`, `PUT` and `DELETE` APIs for CRUD operations.
+* [RESTful APIs With the Play Framework - Part 1](https://dzone.com/articles/restful-apis-with-play-framework-part-1) & [RESTful APIs With the Play Framework — Part 2](https://dzone.com/articles/restful-apis-with-play-frameworkpartnbsp2): In this two part tutorial, [Mercedes Wyss](https://twitter.com/itrjwyss) gives a look into how to set up your development environment using the Play framework, and how to get Play going on your machine, and later at creating RESTful APIs exploring how to handle JSON in your code.
+* [Creating forms on your Play application - Part 1](https://pedrorijo.com/blog/play-forms/) & [Creating forms on your Play application - Part 2](https://pedrorijo.com/blog/advanced-play-forms/): Pedro Rijo goes from basic to advanced examples showing the helpers that Play provides when dealing with HTML forms, how to validate some inputs, and how does Play deals with those input errors.
+* [React with Play Framework 2.6.x](https://medium.com/@yohan.gz/react-with-play-framework-2-6-x-a6e15c0b7bd): Yohan Gomez explains the pros and cons of different approaches when integrating React and Play, and later how to structure your project when using both. There are seed projects for both Java and Scala.
+* [Angular 6 with Play Framework 2.6.x](https://medium.com/@yohan.gz/https-medium-com-yohan-gz-angular-with-play-framework-a6c3f8b339f3): Again Yohan Gomez explains how to integrate Play and modern frontend frameworks, but this time with Angular 6. There are seed projects for both Java and Scala.
+* [Internationalization with Play Framework](https://blog.knoldus.com/internationalization-with-play-framework2-6-x/): Teena Vashist demonstrate how your application can support different languages using Play Framework 2.6.
+* [Authentication using Actions in Play Framework](https://blog.knoldus.com/authentication-using-actions-in-play-framework/): Geetika Gupta demonstrates how to use Action Composition to handle authentication in Play applications.
+* [Streaming data from PostgreSQL using Akka Streams and Slick in Play Framework](https://blog.knoldus.com/streaming-data-from-postgresql-using-akka-streams-and-slick-in-play-framework/): In this blog post, Sidharth Khattri explains the process wherein you can stream data directly from PostgreSQL database using Scala Slick (which is Scala’s database access/query library) and Akka Streams.
+* [Stream a file to AWS S3 using Akka Streams (via Alpakka) in Play Framework](https://blog.knoldus.com/stream-a-file-to-aws-s3-using-akka-streams-via-alpakka-in-play-framework/): In this blog post Sidharth Khattri explains how a file can be streamed from a client (eg: browser) to Amazon S3 using [Alpakka's](https://developer.lightbend.com/docs/alpakka/current/) AWS [S3 connector](https://developer.lightbend.com/docs/alpakka/current/s3.html).
+
+### 2.5.x
+
+#### Play Framework Tutorial Video Series
+
+A tutorial video series by Radix Code provides an initial overview to Play, walking through initial IDE setup, defining routes, creating a CRUD application, enabling ORM support, and customizing the views with bootstrap.
+
+* [Debug Play Application in IntelliJ IDE](https://www.youtube.com/watch?v=RVKU9JvZmao)
+* [Debug Play Application in Eclipse IDE](https://www.youtube.com/watch?v=f9TQD_V7rLg)
+* [How Routing Works](https://www.youtube.com/watch?v=SnQQYl4xsN8)
+* [Add Support for MySQL in Play](https://www.youtube.com/watch?v=J22fr8gQn2c)
+* [Include Bootstrap and jQuery](https://www.youtube.com/watch?v=XyoZnTBUM5I)
+* [Form Validations](https://www.youtube.com/watch?v=Wec-mbjQsrk)
+* [Creating Custom Error Pages](https://www.youtube.com/watch?v=nhKpMrT2EZA)
+
+#### Dependency Injection
+
+* [Dependency Injection in Play Framework using Scala](https://www.schibsted.pl/blog/dependency-injection-play-framework-scala/) by Krzysztof Pado.
+
+#### Akka Streams
+
+* [Akka Streams integration in Play Framework 2.5](https://loicdescotte.github.io/posts/play25-akka-streams/) by Loïc Descotte.
+* [Playing with Akka Streams and Twitter](https://loicdescotte.github.io/posts/play-akka-streams-twitter/) by Loïc Descotte.
+
+#### Database
+
+* [Play Database Application using Slick, Bootstrap](https://www.lightbend.com/activator/template/activator-play-slick-app): This is an example project for showcasing best practices and providing a seed for starting with Play & Slick, By [Knoldus](https://www.knoldus.com/home.knol).
+
+#### Forms and Validators
+
+* [Controller Forms](http://queirozf.com/entries/play2-scala-forms-and-validations): This provides examples of using forms and custom validators within a controller.
+* [Json Validators](http://queirozf.com/entries/fully-customized-json-validator-for-play-framework-2): This guide lists methods of validating json against a customized case class or trait.
+
+#### REST APIs
+
+* [Making a REST API in Play](https://github.com/playframework/play-rest-api), a multi-part guide using the Scala API, by the Lightbend Play Team.
+* [Play API REST Template](https://github.com/adrianhurt/play-api-rest-seed) by Adrianhurt: shows how to implement a complete Json RESTful API with some characteristics such as Authentication Token, pagination, filtering, sorting and searching and optional enveloping.
+
+#### Sub-projects
+
+* [Play Multidomain Seed](https://github.com/adrianhurt/play-multidomain-seed) by Adrianhurt: tries to be a skeleton for a simple multidomain project (www.myweb.com and admin.myweb.com). It shows you how to use subprojects for that and how to share common code. It is also ready to use with Webjars, CoffeeScript, LESS, RequireJS, assets Gzip and assets fingerprinting. Please, check the readme file for more details.
+* [Play Multidomain Auth](https://github.com/adrianhurt/play-multidomain-auth) by Adrianhurt: this is a second part of play-multidomain-seed project. This project tries to be an example of how to implement an Authentication and Authorization layer using the Silhouette authentication library. It also uses [Play-Bootstrap](https://adrianhurt.github.io/play-bootstrap/) for easy template scaffolding.
+
+#### Upgrading
+
+* [Upgrading from Play 2.3 to Play 2.5](https://www.lucidchart.com/techblog/2017/02/22/upgrading-play-framework-2-3-play-2-5/) by Gregg Hernandez: Learn how to deal with common problems when upgrading to Play 2.5, including maintaining legacy behavior, transitioning to Akka Streams, and implementing compile-time dependency injection.
+
+### 2.4.x
+
+#### Semisafe
+
+Semisafe has an excellent series on Play in general:
+
+* [Templates, Routes and AJAX](http://semisafe.com/coding/2015/03/31/play_basics_templates_and_ajax.html)
+* [Upgrading the Framework](http://semisafe.com/coding/2015/06/01/play_basics_upgrading_the_framework.html)
+* [Database Access](http://semisafe.com/coding/2015/06/12/play_basics_database_access.html)
+* [Async Futures and Actors](http://semisafe.com/coding/2015/06/22/play_basics_async_futures_and_actors.html)
+* [Optimistic Future Composition](http://semisafe.com/coding/2015/07/14/play_basics_optimistic_future_composition.html)
+* [React UI Coffeescript](http://semisafe.com/coding/2015/07/24/play_basics_ui_react_coffeescript.html)
+* [CSRF Protection](http://semisafe.com/coding/2015/08/03/play_basics_csrf_protection.html)
+
+#### Minimal Play
+
+* [A Play Application in 38 Lines](https://beachape.com/blog/2015/07/25/slim-play-app/) by Lloyd Chan, showing a "Sinatra" style of Play application.
+
+#### Dependency Injection
+
+* [Playframework 2.4 Dependency Injection (DI)](http://mariussoutier.com/blog/2015/12/06/playframework-2-4-dependency-injection-di/) by Marius Soutier.
+* [Testing with Dependency Injection](http://www.michaelpollmeier.com/2015/09/25/playframework-guice-di) by Michael Pollmeier.
+* [Compile Time Dependency Injection with Play 2.4](https://loicdescotte.github.io/posts/play24-compile-time-di/) by Loïc Descotte.
+
+#### REST APIs
+
+Justin Rodenbostel of SPR Consulting also has two blog posts on building REST APIs in Play:
+
+* [Building a Simple REST API with Scala & Play! (PART 1)](https://spr.com/building-a-simple-rest-api-with-scala-play-part-1/)
+* [Building a Simple REST API with Scala & Play! (PART 2)](https://spr.com/building-a-simple-rest-api-with-scala-play-part-2/)
+
+#### Slick
+
+* [Play framework, Slick and MySQL Tutorial](https://pedrorijo.com/blog/play-slick/) by Pedro Rijo.
+
+#### RethinkDB
+
+* [A classic CRUD application with Play 2.4.x, Scala and RethinkDB](https://rklicksolutions.wordpress.com/2016/02/03/play-2-4-x-rethinkdb-crud-application/) by [Rklick](https://github.com/rklick-solutions).
+
+#### Forms
+
+* [How to add a form to a Play application](https://www.theguardian.com/info/developer-blog/2015/dec/30/how-to-add-a-form-to-a-play-application) by Chris Birchall of the Guardian.
+
+#### EmberJS
+
+* [HTML 5 Device Orientation with play, ember and websockets](https://www.cakesolutions.net/teamblogs/go-reactive-activator-contest-reactive-orientation) by Cake Solutions (with [activator template](https://www.lightbend.com/activator/template/reactive-orientation)).
+
+#### AngularJS, RequireJS and sbt-web
+
+Marius Soutier has an excellent series on setting up a Javascript interface using AngularJS with Play and sbt-web. It was originally written for Play 2.1.x, but has been updated for Play 2.4.x.
+
+* [RequireJS Optimization with Play 2.1 and WebJars](http://mariussoutier.com/blog/2013/08/25/requirejs-optimization-play-webjars/)
+* [Intro to sbt-web](http://mariussoutier.com/blog/2014/10/20/intro-sbt-web/)
+* [Understanding sbt and sbt-web settings](http://mariussoutier.com/blog/2014/12/07/understanding-sbt-sbt-web-settings/)
+* [Play Angular Require Seed Updates](http://mariussoutier.com/blog/2015/07/25/play-angular-require-seed-updates/)
+
+#### React JS
+
+* [ReactJS Tutorial with Play, Scala and WebJars](http://ticofab.io/react-js-tutorial-with-play_scala_webjars/) by Fabio Tiriticco.
+* [A basic example to render UI using ReactJS with Play 2.4.x, Scala and Anorm](https://blog.knoldus.com/2015/07/19/playing-reactjs/) by Knoldus / [activator template](https://github.com/knoldus/playing-reactjs#master).
+
+### 2.3.x
+
+#### REST APIs
+
+* [Playing with Play Framework 2.3.x: REST, pipelines, and Scala](https://shinesolutions.com/2015/04/21/playing-with-play-framework-2-3-x-rest-pipelines-and-scala/) by Sampson Oliver.
+
+#### Anorm
+
+Knoldus has a nice series of blog posts on Anorm:
+
+* [Employee-Self-Service – Building Reactive Play application with Anorm SQL data access – (Part-1)](https://blog.knoldus.com/2014/03/24/employee-self-service-building-reactive-play-application-with-anorm-sql-data-access/)
+* [Employee-Self-Service – Building Reactive Play application with Anorm SQL data access – (Part-2)](https://blog.knoldus.com/2014/03/31/employee-self-service-2/)
+* [Employee-Self-Service: Reactive and Non-Blocking Database Access using Play Framework and Anorm – (Part-3)](https://blog.knoldus.com/2014/04/06/employee-self-service-3/)
+* [Employee-Self-Service: Reactive and Non-Blocking Database Access using Play Framework and Anorm – (Part-4)](https://blog.knoldus.com/2014/04/13/employee-self-service-reactive-and-non-blocking-database-access-using-play-framework-and-anorm-part-4/)
+
+#### Forms
+
+* [Example form including multiple checkboxes and selection](https://ics-software-engineering.github.io/play-example-form/) by Philip Johnson.
+* [UX-friendly conditional form mapping in Play](http://ntcoding.com/blog/2016/02/play-framework-conditional-form-mappings) by Nick Tune.
+
+### 2.2.x
+
+#### Advanced Routing
+
+* [Advanced routing in Play Framework](https://jazzy.id.au/2013/05/08/advanced_routing_in_play_framework.html) by James Roper.
+* [Play Routes – Part 1, Basics](http://mariussoutier.com/blog/2012/12/10/playframework-routes-part-1-basics/) by Marius Soutier.
+* [Play Routes – Part 2, Advanced Use Cases](http://mariussoutier.com/blog/2012/12/11/playframework-routes-part-2-advanced/) by Marius Soutier.
+
+#### Path Bindables
+
+* [How to implement a custom PathBindable with Play 2](http://julien.richard-foy.fr/blog/2012/04/09/how-to-implement-a-custom-pathbindable-with-play-2/) by Julien Richard-Foy.
+
+#### Templates
+
+* [Play Framework 2.0 Templates – Part 1, Parameters](http://mariussoutier.com/blog/2012/04/27/play-framework-2-0-templates-part-1-parameters/) by Marius Soutier.
+
+#### User Interface
+
+* [Composite user interface without boilerplate using Play 2](http://julien.richard-foy.fr/blog/2012/02/26/composite-user-interface-without-boilerplate-using-play-2/) by Julien Foy.
+
+#### Play in Practice
+
+* [Play in Practice](https://tersesystems.com/2013/04/20/play-in-practice/) by Will Sargent.
diff --git a/manual/tutorial/code/javaguide/hello/HelloController.java b/manual/tutorial/code/javaguide/hello/HelloController.java
new file mode 100644
index 00000000..47cb7112
--- /dev/null
+++ b/manual/tutorial/code/javaguide/hello/HelloController.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package javaguide.hello;
+
+import play.mvc.*;
+
+public class HelloController extends Controller {
+
+ // #hello-world-index-action
+ public Result index() {
+ // ###replace: ok(views.html.index.render());
+ return ok(javaguide.hello.html.index.render());
+ }
+ // #hello-world-index-action
+
+ // #hello-world-hello-action
+ public Result hello() {
+ // ###replace: return ok(views.html.hello.render());
+ return ok(javaguide.hello.html.hello.render());
+ }
+ // #hello-world-hello-action
+
+ /*
+ //#hello-world-hello-error-action
+ public Result hello(String name) {
+ return ok(views.html.hello.render());
+ }
+ //#hello-world-hello-error-action
+ */
+
+ // #hello-world-hello-correct-action
+ public Result hello(String name) {
+ // ###replace: return ok(views.html.hello.render(name));
+ return ok(javaguide.hello.html.helloName.render(name));
+ }
+ // #hello-world-hello-correct-action
+}
diff --git a/manual/tutorial/code/javaguide/hello/hello.scala.html b/manual/tutorial/code/javaguide/hello/hello.scala.html
new file mode 100644
index 00000000..87e2b7f2
--- /dev/null
+++ b/manual/tutorial/code/javaguide/hello/hello.scala.html
@@ -0,0 +1,9 @@
+@* #hello-world-page *@
+@main("Hello") {
+
+}
+@* #hello-world-page *@
\ No newline at end of file
diff --git a/manual/tutorial/code/javaguide/hello/helloName.scala.html b/manual/tutorial/code/javaguide/hello/helloName.scala.html
new file mode 100644
index 00000000..e894a33a
--- /dev/null
+++ b/manual/tutorial/code/javaguide/hello/helloName.scala.html
@@ -0,0 +1,9 @@
+@(name: String)
+@main("Hello") {
+
+}
+@* #hello-world-page *@
\ No newline at end of file
diff --git a/manual/tutorial/code/javaguide/hello/index.scala.html b/manual/tutorial/code/javaguide/hello/index.scala.html
new file mode 100644
index 00000000..15a6e995
--- /dev/null
+++ b/manual/tutorial/code/javaguide/hello/index.scala.html
@@ -0,0 +1,3 @@
+@main("Hello") {
+ Index view
+}
\ No newline at end of file
diff --git a/manual/tutorial/code/javaguide/hello/main.scala.html b/manual/tutorial/code/javaguide/hello/main.scala.html
new file mode 100644
index 00000000..e4385b6c
--- /dev/null
+++ b/manual/tutorial/code/javaguide/hello/main.scala.html
@@ -0,0 +1,11 @@
+@(title: String)(content: play.twirl.api.Html)
+
+
+
+
+ @title
+
+
+ @content
+
+
diff --git a/manual/tutorial/code/routes b/manual/tutorial/code/routes
new file mode 100644
index 00000000..d18b32d5
--- /dev/null
+++ b/manual/tutorial/code/routes
@@ -0,0 +1,11 @@
+# #hello-world-index-route
+GET / controllers.HomeController.index
+# #hello-world-index-route
+
+# #hello-world-hello-route
+GET /hello controllers.HomeController.hello
+# #hello-world-hello-route
+
+# #hello-world-hello-name-route
+# ###insert: GET /hello controllers.HomeController.hello(name: String)
+# #hello-world-hello-name-route
\ No newline at end of file
diff --git a/manual/tutorial/code/scalaguide/hello/HelloController.scala b/manual/tutorial/code/scalaguide/hello/HelloController.scala
new file mode 100644
index 00000000..1f49d4d3
--- /dev/null
+++ b/manual/tutorial/code/scalaguide/hello/HelloController.scala
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package scalaguide.hello {
+ import play.api.mvc._
+ import javax.inject.Inject
+
+ package views {
+
+ import play.twirl.api.Html
+
+ object html {
+ def index(): Html = Html("Index page")
+ def hello(): Html = Html("Hello page")
+ def hello(name: String): Html = Html(s"Hello $name")
+ }
+ }
+
+ class HelloController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {
+
+ //#hello-world-index-action
+ def index = Action {
+ Ok(views.html.index())
+ }
+ //#hello-world-index-action
+
+ //#hello-world-hello-action
+ def hello = Action {
+ Ok(views.html.hello())
+ }
+ //#hello-world-hello-action
+
+ /*
+ //#hello-world-hello-error-action
+ def hello(name: String) = Action {
+ Ok(views.html.hello())
+ }
+ //#hello-world-hello-error-action
+ */
+
+ //#hello-world-hello-correct-action
+ def hello(name: String) = Action {
+ Ok(views.html.hello(name))
+ }
+ //#hello-world-hello-correct-action
+ }
+}
diff --git a/manual/tutorial/images/hello-error.png b/manual/tutorial/images/hello-error.png
new file mode 100644
index 00000000..381fde2a
Binary files /dev/null and b/manual/tutorial/images/hello-error.png differ
diff --git a/manual/tutorial/images/hello-name.png b/manual/tutorial/images/hello-name.png
new file mode 100644
index 00000000..7e6c1659
Binary files /dev/null and b/manual/tutorial/images/hello-name.png differ
diff --git a/manual/tutorial/images/hello-page.png b/manual/tutorial/images/hello-page.png
new file mode 100644
index 00000000..d9009833
Binary files /dev/null and b/manual/tutorial/images/hello-page.png differ
diff --git a/manual/tutorial/images/play-request-response.png b/manual/tutorial/images/play-request-response.png
new file mode 100644
index 00000000..03d8b946
Binary files /dev/null and b/manual/tutorial/images/play-request-response.png differ
diff --git a/manual/tutorial/images/play-stack.png b/manual/tutorial/images/play-stack.png
new file mode 100644
index 00000000..b4728d5f
Binary files /dev/null and b/manual/tutorial/images/play-stack.png differ
diff --git a/manual/tutorial/index.toc b/manual/tutorial/index.toc
new file mode 100644
index 00000000..b86d9e6b
--- /dev/null
+++ b/manual/tutorial/index.toc
@@ -0,0 +1,4 @@
+HelloWorldTutorial: Hello World Tutorial
+PlayApplicationOverview: Play Application Overview
+ImplementingHelloWorld: Implementing Hello World
+Tutorials:Play Tutorials
\ No newline at end of file
diff --git a/manual/working/commonGuide/Modules.md b/manual/working/commonGuide/Modules.md
new file mode 100644
index 00000000..e9a1f52b
--- /dev/null
+++ b/manual/working/commonGuide/Modules.md
@@ -0,0 +1,22 @@
+
+# Extending Play with modules
+
+At its core, Play is a very lightweight HTTP server, providing mechanisms for serving HTTP requests, but not much else. Additional functionality in Play is provided through the use of Play modules.
+
+## What is a module?
+
+There is no strict definition in Play of what a module is or isn't - a module could be just a library that provides some helper methods to help you do something, or it could be a full framework providing complex functionality such as user management. Some modules are built in to Play, others are written and maintained by members of the Play community.
+
+Some modules provide components - objects that represent resources, for example a database connection. These objects may have a lifecycle and need to be started and stopped when the application starts and stops, and they may hold some state such as a cache. Play provides a variety of mechanisms for accessing and using these components. Components are not only provided by modules, they may be provided by the application themselves.
+
+## Accessing modules
+
+One of the earliest decisions that you need to make when starting a new Play project is how you will access the components provided by modules. Components are accessed through the use of a dependency injection mechanism, where rather than having your components look up other components in the system, your components declare what other components they need, and the system injects those components into your components.
+
+At its core, Play is agnostic to any particular form of dependency injection, however out of the box Play provides and we recommend that you use [Guice](https://github.com/google/guice). The remainder of this documentation will assume that this is the decision that you have made, however there will be examples of how to integrate with other dependency injection mechanisms.
+
+You can read more about dependency injection in [[Scala|ScalaDependencyInjection]] or [[Java|JavaDependencyInjection]].
+
+## Community modules
+
+Play has a list of [[community-developed modules|ModuleDirectory]] that may provide functionality you need or serve as examples of how to write a module.
diff --git a/manual/working/commonGuide/assets/Assets.md b/manual/working/commonGuide/assets/Assets.md
new file mode 100644
index 00000000..06a336fa
--- /dev/null
+++ b/manual/working/commonGuide/assets/Assets.md
@@ -0,0 +1,11 @@
+
+# Static assets
+
+This section covers serving your application’s static resources such as JavaScript, CSS and images.
+
+- [[Working with public assets|AssetsOverview]]
+- [[Using CoffeeScript|AssetsCoffeeScript]]
+- [[Using LESS CSS|AssetsLess]]
+- [[Using Sass|AssetsSass]]
+- [[Using JSHint|AssetsJSHint]]
+- [[Using RequireJs|RequireJS-support]]
diff --git a/manual/working/commonGuide/assets/AssetsCoffeeScript.md b/manual/working/commonGuide/assets/AssetsCoffeeScript.md
new file mode 100644
index 00000000..04e15a53
--- /dev/null
+++ b/manual/working/commonGuide/assets/AssetsCoffeeScript.md
@@ -0,0 +1,39 @@
+
+# Using CoffeeScript
+
+[CoffeeScript](https://coffeescript.org/) is a small and elegant language that compiles into JavaScript. It provides a nice syntax for writing JavaScript code.
+
+Compiled assets in Play must be defined in the `app/assets` directory. They are handled by the build process and CoffeeScript sources are compiled into standard JavaScript files. The generated JavaScript files are distributed as standard resources into the same `public/` folder as other unmanaged assets, meaning that there is no difference in the way you use them once compiled.
+
+For example a CoffeeScript source file `app/assets/javascripts/main.coffee` will be available as a standard JavaScript resource, at `public/javascripts/main.js`.
+
+CoffeeScript sources are compiled automatically during an `assets` command, or when you refresh any page in your browser while you are running in development mode. Any compilation errors will be displayed in your browser:
+
+[[images/coffeeError.png]]
+
+## Layout
+
+Here is an example layout for using CoffeeScript in your projects:
+
+```
+app
+ └ assets
+ └ javascripts
+ └ main.coffee
+```
+
+You can use the following syntax to use the compiled JavaScript file in your template:
+
+```html
+
+```
+
+Note the `lib/requirejs/require.js` path. The `lib` folder denotes the extracted WebJar assets, the `requirejs` folder corresponds to the WebJar artifactId, and the `require.js` refers to the required asset at the root of the WebJar. To clarify, the `requirejs` webjar dependency is declared at your build file like:
+
+```scala
+libraryDependencies += "org.webjars" % "requirejs" % "2.2.0"
+```
+
+## How are public assets packaged?
+
+During the build process, the contents of the `public` folder are processed and added to the application classpath.
+
+When you package your application, all assets for the application, including all sub projects, are aggregated into a single jar, in `target/my-first-app-1.0.0-assets.jar`. This jar is included in the distribution so that your Play application can serve them. This jar can also be used to deploy the assets to a CDN or reverse proxy.
+
+## The Assets controller
+
+Play comes with a built-in controller to serve public assets. By default, this controller provides caching, ETag, gzip and compression support. There are two different styles that the Assets controller supports: the first is to use Play's configuration, and the second is to use pass the assets path directly to the controller.
+
+### Binding the Assets components
+
+If you are using runtime dependency injection, Play already provides bindings in the `AssetsModule`, which is loaded by default. (If you are not using assets, you can disable this module by adding the configuration `play.modules.disabled += controllers.AssetsModule`.). The bindings there make `Assets` class injectable.
+
+If you are using components traits to do compile-time dependency injection, you should mix in `controllers.AssetsComponents`. Then the controller will be available as `assets: Assets`. You do not need to construct the controller yourself.
+
+### Using assets with configuration
+
+For the most common case where you only have one place where assets are centrally located, you can use configuration to specify the location:
+
+```
+play.assets {
+ path = "/public"
+ urlPrefix = "/assets"
+}
+```
+
+And use the `Assets.at` method with one parameter:
+
+```scala
+Assets.at(file: String)
+```
+
+Then in routes:
+
+@[assets-configured-path](code/configured.assets.routes)
+
+### Passing the assets path directly
+
+The `Assets` controller also defines an `at` action with two parameters:
+
+```scala
+Assets.at(path: String, file: String)
+```
+
+The `path` parameter must be fixed and defines the directory managed by the action. The `file` parameter is usually dynamically extracted from the request path.
+
+Here is the typical mapping of the `Assets` controller in your `conf/routes` file:
+
+@[assets-wildcard](code/common.assets.routes)
+
+Note that we define the `*file` dynamic part that will match the `.*` regular expression. So for example, if you send this request to the server:
+
+```
+GET /assets/javascripts/jquery.js
+```
+
+The router will invoke the `Assets.at` action with the following parameters:
+
+```
+controllers.Assets.at("/public", "javascripts/jquery.js")
+```
+
+To route to a single static file, both the path and file have to be specified:
+
+@[assets-single-static-file](code/common.assets.routes)
+
+## Reverse routing for public assets
+
+As for any controller mapped in the routes file, a reverse controller is created in `controllers.routes.Assets`. You use this to reverse the URL needed to fetch a public resource. For example, from a template:
+
+```html
+
+```
+
+In `DEV` mode this will by default produce the following result:
+
+```html
+
+```
+
+If your app is not running in `DEV` mode **and** a `jquery.min.js` or `jquery-min.js` file exists then by default the minified file will be used instead:
+
+```html
+
+```
+
+This makes debugging of JavaScript files easier during development. Of course this not only works for JavaScript files but for any file extension.
+If you don't want Play to automatically resolve the `.min.*` or `-min.*` files, regardless of the mode your application is running in, you can set `play.assets.checkForMinified = false` in your `application.conf` (or to `true` to always resolve the min file, even in `DEV` mode).
+
+Note that we don’t specify the first `folder` parameter when we reverse the route. This is because our routes file defines a single mapping for the `Assets.at` action, where the `folder` parameter is fixed. So it doesn't need to be specified.
+
+However, if you define two mappings for the `Assets.at` action, like this:
+
+@[assets-two-mappings](code/common.assets.routes)
+
+You will then need to specify both parameters when using the reverse router:
+
+```html
+
+
+```
+
+## Reverse routing and fingerprinting for public assets
+
+[sbt-web](https://github.com/sbt/sbt-web) brings the notion of a highly configurable asset pipeline to Play e.g. in your build file:
+
+```scala
+pipelineStages := Seq(rjs, digest, gzip)
+```
+
+The above will order the RequireJs optimizer ([sbt-rjs](https://github.com/sbt/sbt-rjs)), the digester ([sbt-digest](https://github.com/sbt/sbt-digest)) and then compression ([sbt-gzip](https://github.com/sbt/sbt-gzip)). Unlike many sbt tasks, these tasks will execute in the order declared, one after the other.
+
+In essence asset fingerprinting permits your static assets to be served with aggressive caching instructions to a browser. This will result in an improved experience for your users given that subsequent visits to your site will result in less assets requiring to be downloaded. Rails also describes the benefits of [asset fingerprinting](https://guides.rubyonrails.org/asset_pipeline.html#what-is-fingerprinting-and-why-should-i-care-questionmark).
+
+The above declaration of `pipelineStages` and the requisite `addSbtPlugin` declarations in your `plugins.sbt` for the plugins you require are your start point. You must then declare to Play what assets are to be versioned.
+
+There are two ways obtain the real path of a fingerprinted asset. The first way uses static state and supports the same style as normal reverse routing. It does so by looking up assets metadata that's set by a running Play application. The second way is to use configuration and inject an AssetsFinder to find your asset.
+
+### Using reverse routing and static state
+
+If you plan to use the reverse router with static state, the following routes file entry declares that all assets are to be versioned:
+
+```scala
+GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
+```
+
+> **Note:** Make sure you indicate that `file` is an asset by writing `file: Asset`.
+
+You then use the reverse router, for example within a `scala.html` view:
+
+```html
+
+```
+
+The downside of this approach is that it requires special logic that converts the `Asset` from the path you passed in to the final minified path with a digest. It's also more difficult to unit test, since there's no component you can mock to define the path.
+
+### Using configuration and AssetsFinder
+
+You can also define your paths in configuration, and inject an `AssetsFinder` into your controller to get the final path. In your configuration set up the assets `path` (the directory containing assets) and the `urlPrefix` (the prefix to the URL in your application):
+
+```
+play.assets {
+ path = "/public"
+ urlPrefix = "/assets"
+}
+```
+
+In your routes file you can define a route as follows:
+
+@[assets-configured-path-versioned](code/configured.assets.routes)
+
+(you should not use the `: Asset` type annotation here)
+
+Then you can pass an `AssetsFinder` to your template and use that to get the final path:
+
+```html
+@(assetsFinder: AssetsFinder)
+
+
+```
+
+The advantage to this approach is that it requires no static state to set up. That means you can unit test your controllers and templates without a running application by simply passing an instance of `AssetsFinder`. That makes it simple to mock for a unit test by simply implementing the abstract methods that return `String`s.
+
+Using the `AssetsFinder` approach also makes it easy to run multiple self-contained applications at once in the same classloader, since it uses no static state. This can also be helpful for testing.
+
+The `AssetsFinder` interface also works in cases where fingerprinting is not used. It returns the original asset if a fingerprinted and/or minified asset cannot be found.
+
+## Etag support
+
+The `Assets` controller automatically manages **ETag** HTTP Headers. The ETag value is generated from the digest (if `sbt-digest` is being used in the asset pipeline) or otherwise the resource name and the file’s last modification date. If the resource file is embedded into a file, the JAR file’s last modification date is used.
+
+When a web browser makes a request specifying this **Etag** then the server can respond with **304 NotModified**.
+
+## Gzip support
+
+If a resource with the same name but using a `.gz` suffix is found then the `Assets` controller will also serve the latter and add the following HTTP header:
+
+```
+Content-Encoding: gzip
+```
+
+Including the `sbt-gzip` plugin in your build and declaring its position in the `pipelineStages` is all that is required to generate gzip files.
+
+## Additional `Cache-Control` directive
+
+Using Etag is usually enough for the purposes of caching. However if you want to specify a custom `Cache-Control` header for a particular resource, you can specify it in your `application.conf` file. For example:
+
+```
+# Assets configuration
+# ~~~~~
+play.assets.cache."/public/stylesheets/bootstrap.min.css"="max-age=3600"
+```
+
+You can also use partial paths to specify a custom `Cache-Control` for all the assets that are under that path, for example:
+
+```
+# Assets configuration
+# ~~~~~
+play.assets.cache."/public/stylesheets/"="max-age=100"
+play.assets.cache."/public/javascripts/"="max-age=200"
+```
+
+And Play will use `max-age=200` for all assets under `/public/javascripts` (like `/public/javascripts/main.js`) and `max-age=100` to all assets under `/public/stylesheets` (like `/public/stylesheets/main.css`).
+
+### How the additional directives are applied
+
+Play sorts the `Cache-Control` directives lexicographically and later from more specific to less specific. For example, given the following configuration:
+
+```
+# Assets configuration
+# ~~~~~
+play.assets.cache."/public/stylesheets/"="max-age=101"
+play.assets.cache."/public/stylesheets/layout/"="max-age=102"
+play.assets.cache."/public/stylesheets/app/"="max-age=103"
+play.assets.cache."/public/stylesheets/layout/main.css"="max-age=103"
+
+play.assets.cache."/public/javascripts/"="max-age=201"
+play.assets.cache."/public/javascripts/app/"="max-age=202"
+play.assets.cache."/public/javascripts/app/main.js"="max-age=203"
+```
+
+The directives will be sorted and applied in the following order:
+
+```
+play.assets.cache."/public/javascripts/app/main.js"="max-age=203"
+play.assets.cache."/public/javascripts/app/"="max-age=202"
+play.assets.cache."/public/javascripts/"="max-age=201"
+
+play.assets.cache."/public/stylesheets/app/"="max-age=103"
+play.assets.cache."/public/stylesheets/layout/main.css"="max-age=103"
+play.assets.cache."/public/stylesheets/layout/"="max-age=102"
+play.assets.cache."/public/stylesheets/"="max-age=101"
+```
+
+> **Note:** a configuration like `play.assets.cache."/public/stylesheets"="max-age=101"` will match both `public/stylesheets.css` and `public/stylesheets/main.css`, so you may want to add a trailing `/` to better differentiate directories, for example `play.assets.cache."/public/stylesheets/"="max-age=101"`.
+
+## Managed assets
+
+Starting with Play 2.3 managed assets are processed by [sbt-web](https://github.com/sbt/sbt-web#sbt-web) based plugins. Prior to 2.3 Play bundled managed asset processing in the form of CoffeeScript, LESS, JavaScript linting (ClosureCompiler) and RequireJS optimization. The following sections describe sbt-web and how the equivalent 2.2 functionality can be achieved. Note though that Play is not limited to this asset processing technology as many plugins should become available to sbt-web over time. Please check-in with the [sbt-web](https://github.com/sbt/sbt-web#sbt-web) project to learn more about what plugins are available.
+
+Many plugins use sbt-web's [js-engine plugin](https://github.com/sbt/sbt-js-engine). js-engine is able to execute plugins written to the Node API either within the JVM via the excellent [Trireme](https://github.com/apigee/trireme#trireme) project, or directly on [Node.js](https://nodejs.org/) for superior performance. Note that these tools are used during the development cycle only and have no involvement during the runtime execution of your Play application. If you have Node.js installed then you are encouraged to declare the following environment variable. For Unix, if `SBT_OPTS` has been defined elsewhere then you can:
+
+```bash
+export SBT_OPTS="$SBT_OPTS -Dsbt.jse.engineType=Node"
+```
+
+The above declaration ensures that Node.js is used when executing any sbt-web plugin.
+
+## Range requests support
+
+`Assets` controller automatically supports part of [RFC 7233](https://tools.ietf.org/html/rfc7233) which defines how range requests and partial responses works. The `Assets` controller will delivery a `206 Partial Content` if a satisfiable `Range` header is present in the request. It will also returns a `Accept-Ranges: bytes` for all assets delivery.
+
+> **Note:** Besides the fact that some parsing is done to better handle multiple ranges, `multipart/byteranges` is not fully supported yet.
+
+You can also return `206 Partial Content` when delivering files without using the `Assets` controller:
+
+### Scala version
+
+@[range-request](code/assets/controllers/RangeRequestController.scala)
+
+### Java version
+
+@[range-request](code/assets/controllers/JavaRangeRequestController.java)
+
+Both examples will delivery just part of the video file, according to the requested range.
diff --git a/manual/working/commonGuide/assets/AssetsSass.md b/manual/working/commonGuide/assets/AssetsSass.md
new file mode 100644
index 00000000..00f6cb1d
--- /dev/null
+++ b/manual/working/commonGuide/assets/AssetsSass.md
@@ -0,0 +1,95 @@
+
+# Using Sass
+
+[Sass](http://sass-lang.com/) is a dynamic stylesheet language. It allows considerable flexibility in the way you write CSS files including support for variables, mixins and more.
+
+Compilable assets in Play are typically defined in the `app/assets` directory. They are handled by the build process, and Sass sources are compiled into standard CSS files. The generated CSS files are distributed as standard resources into the same `public/` folder as the unmanaged assets, meaning that there is no difference in the way you use them once compiled.
+
+For example, Sass source file `app/assets/stylesheets/main.scss` will be available as standard CSS resource, at `public/stylesheets/main.css`.
+
+Sass sources are compiled automatically during an `assets` command, or when you refresh any page in your browser while you are running in development mode. Any compilation errors will be displayed in your browser:
+
+[[images/sassError.png]]
+
+## Working with partial Sass source files
+
+Any Sass file (`*.scss`/`*.sass`) will automatically be compiled. The Sass plugin will automatically determine which Sass syntax is being used (indented or not) based on the filename. A file who's name starts with an `_` will not be compiled separately. However, such files can be included in other Sass files by using the standard Sass import feature.
+
+## Layout
+
+Below an example layout for using Sass in your project is given:
+
+```
+app
+ └ assets
+ └ stylesheets
+ └ main.scss
+ └ utils
+ └ _reset.scss
+ └ _layout.scss
+```
+
+Given the following `main.scss` source:
+
+```scss
+@import "utils/reset";
+@import "utils/layout";
+
+h1 {
+ color: red;
+}
+```
+
+The Sass file outlined above, will be compiled into `public/stylesheets/main.css`. Hence, this file can be used in your template as any regular public asset:
+
+```html
+
+```
+
+## Mixing Sass and web-jars
+
+[WebJars](https://www.webjars.org) enable us to depend on client libraries without pulling all dependencies into our own code base manually.
+
+Compass is a library containing all sorts of reusable functions and mixins for Sass. Unfortunately, this library is targeted towards the Ruby implementation of Sass. There is a number of useful mixins that can be extracted from it. Fortunately, these mixins are wrapped in a web-jar.
+
+To include these compass mixins in your project is as easy as including the web-jar dependency in your library dependencies. For example, within a `build.sbt` file:
+
+```scala
+libraryDependencies += "org.webjars.bower" % "compass-mixins" % "0.12.7"
+```
+
+sbt-web will automatically extract WebJars into a `lib` directory relative to your asset's target directory. Therefore to use the Compass mixins you can import the mixins by:
+
+```scss
+@import "lib/compass-mixins/lib/compass";
+
+table.ellipsed-table {
+ tr td {
+ max-width: 100px;
+ @include ellipsis();
+ }
+}
+```
+
+The same idea can be used to include other Sass libraries, for instance the [official Sass port of bootstrap](https://github.com/twbs/bootstrap-sass). To include the WebJar use:
+
+```scala
+libraryDependencies += "org.webjars.bower" % "bootstrap-sass" % "3.3.6"
+```
+
+Then to use it in your project, you can use:
+
+```scss
+@import "lib/bootstrap-sass/assets/stylesheets/bootstrap";
+```
+
+## Enablement and Configuration
+
+Sass compilation is enabled by simply adding the sbt-sassify plugin to your plugins.sbt file when using the `PlayJava` or `PlayScala` plugins:
+
+```scala
+addSbtPlugin("org.irundaia.sbt" % "sbt-sassify" % "1.4.11")
+```
+
+The plugin's default configuration should normally be sufficient. However please refer to the [plugin's documentation](https://github.com/irundaia/sbt-sassify#options) for information on how it may be configured as well as its latest version.
+
diff --git a/manual/working/commonGuide/assets/RequireJS-support.md b/manual/working/commonGuide/assets/RequireJS-support.md
new file mode 100644
index 00000000..44f69f26
--- /dev/null
+++ b/manual/working/commonGuide/assets/RequireJS-support.md
@@ -0,0 +1,40 @@
+
+# RequireJS
+
+According to [RequireJS](https://requirejs.org/)' website
+
+> RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments... Using a modular script loader like RequireJS will improve the speed and quality of your code.
+
+What this means in practice is that one can use [RequireJS](https://requirejs.org/) to modularize your JavaScript. RequireJS achieves this by implementing a semi-standard API called [Asynchronous Module Definition](http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition) (other similar ideas include [CommonJS](http://www.commonjs.org/) ). Using AMD makes it is possible to resolve and load javascript modules on the _client side_ while allowing server side _optimization_. For server side optimization module dependencies may be minified and combined using [UglifyJS 2](https://github.com/mishoo/UglifyJS2#uglifyjs-2).
+
+By convention RequireJS expects a main.js file to bootstrap its module loader.
+
+## Deployment
+
+The RequireJS optimizer shouldn't generally kick-in until it is time to perform a deployment i.e. by running the `start`, `stage` or `dist` tasks.
+
+If you're using WebJars with your build then the RequireJS optimizer plugin will also ensure that any JavaScript resources referenced from within a WebJar are automatically referenced from the [jsdelivr](https://www.jsdelivr.com) CDN. In addition if any `.min.js` file is found then that will be used in place of `.js`. An added bonus here is that there is no change required to your html!
+
+## Enablement and Configuration
+
+RequireJS optimization is enabled by simply adding the plugin to your plugins.sbt file when using the `PlayJava` or `PlayScala` plugins:
+
+```scala
+addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.9")
+```
+
+To add the plugin to the asset pipeline you can declare it as follows (assuming just the one plugin for the pipeline - add others into the sequence such as digest and gzip as required):
+
+```scala
+pipelineStages := Seq(rjs)
+```
+
+A standard build profile for the RequireJS optimizer is provided and should suffice for most projects. However please refer to the [plugin's documentation](https://github.com/sbt/sbt-rjs#sbt-rjs) for information on how it may be configured.
+
+Note that RequireJS performs a lot of work and while it works when executed in-JVM under Trireme, you will be best to use Node.js as the js-engine from a performance perspective. For convenience you can set the `sbt.jse.engineType` property in `SBT_OPTS`. For example on Unix:
+
+```bash
+export SBT_OPTS="$SBT_OPTS -Dsbt.jse.engineType=Node"
+```
+
+Please refer to the [plugin's documentation](https://github.com/sbt/sbt-rjs#sbt-rjs) for information on how it may be configured.
diff --git a/manual/working/commonGuide/assets/code/CommonAssets.scala b/manual/working/commonGuide/assets/code/CommonAssets.scala
new file mode 100644
index 00000000..729e5001
--- /dev/null
+++ b/manual/working/commonGuide/assets/code/CommonAssets.scala
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package common.assets
+
+package object controllers {
+ type Assets = _root_.controllers.Assets
+}
diff --git a/manual/working/commonGuide/assets/code/ConfiguredAssets.scala b/manual/working/commonGuide/assets/code/ConfiguredAssets.scala
new file mode 100644
index 00000000..a7489ffc
--- /dev/null
+++ b/manual/working/commonGuide/assets/code/ConfiguredAssets.scala
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package configured.assets
+
+package object controllers {
+ type Assets = _root_.controllers.Assets
+}
diff --git a/manual/working/commonGuide/assets/code/assets/controllers/JavaRangeRequestController.java b/manual/working/commonGuide/assets/code/assets/controllers/JavaRangeRequestController.java
new file mode 100644
index 00000000..12d4eea6
--- /dev/null
+++ b/manual/working/commonGuide/assets/code/assets/controllers/JavaRangeRequestController.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package assets.controllers;
+
+import play.mvc.*;
+
+import java.io.File;
+
+public class JavaRangeRequestController extends Controller {
+
+ // #range-request
+ public Result video(Long videoId) {
+ File videoFile = getVideoFile(videoId);
+ return RangeResults.ofFile(videoFile);
+ }
+ // #range-request
+
+ private File getVideoFile(Long videoId) {
+ return new File("video.mp4");
+ }
+}
diff --git a/manual/working/commonGuide/assets/code/assets/controllers/RangeRequestController.scala b/manual/working/commonGuide/assets/code/assets/controllers/RangeRequestController.scala
new file mode 100644
index 00000000..40153f53
--- /dev/null
+++ b/manual/working/commonGuide/assets/code/assets/controllers/RangeRequestController.scala
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package assets.controllers
+
+import java.io.File
+import javax.inject.Inject
+
+import play.api.mvc._
+
+class RangeRequestController @Inject()(c: ControllerComponents) extends AbstractController(c) {
+
+ // #range-request
+ def video(videoId: Long) = Action { implicit request =>
+ val videoFile = getVideoFile(videoId)
+ RangeResult.ofFile(videoFile, request.headers.get(RANGE), Some("video/mp4"))
+ }
+ // #range-request
+
+ private def getVideoFile(videoId: Long) = new File("video.mp4")
+}
diff --git a/manual/working/commonGuide/assets/code/common.assets.routes b/manual/working/commonGuide/assets/code/common.assets.routes
new file mode 100644
index 00000000..9502fda6
--- /dev/null
+++ b/manual/working/commonGuide/assets/code/common.assets.routes
@@ -0,0 +1,13 @@
+#assets-wildcard
+GET /assets/*file controllers.Assets.at(path="/public", file)
+#assets-wildcard
+
+#assets-single-static-file
+GET /favicon.ico controllers.Assets.at(path="/public", file="favicon.ico")
+#assets-single-static-file
+
+#assets-two-mappings
+GET /javascripts/*file controllers.Assets.at(path="/public/javascripts", file)
+GET /images/*file controllers.Assets.at(path="/public/images", file)
+#assets-two-mappings
+
diff --git a/manual/working/commonGuide/assets/code/configured.assets.routes b/manual/working/commonGuide/assets/code/configured.assets.routes
new file mode 100644
index 00000000..898d3e24
--- /dev/null
+++ b/manual/working/commonGuide/assets/code/configured.assets.routes
@@ -0,0 +1,7 @@
+#assets-configured-path
+GET /assets/*file controllers.Assets.at(file)
+#assets-configured-path
+
+#assets-configured-path-versioned
+GET /assets/*file controllers.Assets.versioned(file)
+#assets-configured-path-versioned
diff --git a/manual/detailedTopics/assets/images/ClosureError.png b/manual/working/commonGuide/assets/images/ClosureError.png
similarity index 100%
rename from manual/detailedTopics/assets/images/ClosureError.png
rename to manual/working/commonGuide/assets/images/ClosureError.png
diff --git a/manual/detailedTopics/assets/images/coffeeError.png b/manual/working/commonGuide/assets/images/coffeeError.png
similarity index 100%
rename from manual/detailedTopics/assets/images/coffeeError.png
rename to manual/working/commonGuide/assets/images/coffeeError.png
diff --git a/manual/detailedTopics/assets/images/lessError.png b/manual/working/commonGuide/assets/images/lessError.png
similarity index 100%
rename from manual/detailedTopics/assets/images/lessError.png
rename to manual/working/commonGuide/assets/images/lessError.png
diff --git a/manual/working/commonGuide/assets/images/sassError.png b/manual/working/commonGuide/assets/images/sassError.png
new file mode 100644
index 00000000..b62d40f6
Binary files /dev/null and b/manual/working/commonGuide/assets/images/sassError.png differ
diff --git a/manual/working/commonGuide/assets/index.toc b/manual/working/commonGuide/assets/index.toc
new file mode 100644
index 00000000..41643251
--- /dev/null
+++ b/manual/working/commonGuide/assets/index.toc
@@ -0,0 +1,7 @@
+Assets:Static assets
+AssetsOverview:Working with public assets
+AssetsCoffeeScript:Using CoffeeScript
+AssetsLess:Using LESS CSS
+AssetsSass:Using Sass
+AssetsJSHint:Using JSHint
+RequireJS-support:Using RequireJs
\ No newline at end of file
diff --git a/manual/working/commonGuide/build/AggregatingReverseRouters.md b/manual/working/commonGuide/build/AggregatingReverseRouters.md
new file mode 100644
index 00000000..6b677c5e
--- /dev/null
+++ b/manual/working/commonGuide/build/AggregatingReverseRouters.md
@@ -0,0 +1,14 @@
+
+# Aggregating reverse routers
+
+In some situations you want to share reverse routers between sub projects that are not dependent on each other.
+
+For example, you might have a `web` sub project, and an `api` sub project. These sub projects may have no dependence on each other, except that the `web` project wants to render links to the `api` project (for making AJAX calls), while the `api` project wants to render links to the `web` (rendering the web link for a resource in JSON). In this situation, it would be convenient to use the reverse router, but since these projects don't depend on each other, you can't.
+
+Play's routes compiler offers a feature that allows a common dependency to generate the reverse routers for projects that depend on it so that the reverse routers can be shared between those projects. This is configured using the `aggregateReverseRoutes` sbt configuration item, like this:
+
+@[content](code/aggregate.sbt)
+
+In this setup, the reverse routers for `api` and `web` will be generated as part of the `common` project. Meanwhile, the forwards routers for `api` and `web` will still generate forwards routers, but not reverse routers, because their reverse routers have already been generated in the `common` project which they depend on, so they don't need to generate them.
+
+> Note that the `common` project has a type of `Project` explicitly declared. This is because there is a recursive reference between it and the `api` and `web` projects, through the `dependsOn` method and `aggregateReverseRoutes` setting, so the Scala type checker needs an explicit type somewhere in the chain of recursion.
diff --git a/manual/working/commonGuide/build/Build.md b/manual/working/commonGuide/build/Build.md
new file mode 100644
index 00000000..96d36c6d
--- /dev/null
+++ b/manual/working/commonGuide/build/Build.md
@@ -0,0 +1,14 @@
+
+# The build system
+
+This section gives details about Play's build system.
+
+- [[Overview of the build system|BuildOverview]]
+- [[About sbt settings|sbtSettings]]
+- [[Manage application dependencies|sbtDependencies]]
+- [[Working with sub-projects|sbtSubProjects]]
+- [[Play enhancer|PlayEnhancer]]
+- [[Aggregating reverse routers|AggregatingReverseRouters]]
+- [[Improving Compilation Times|CompilationSpeed]]
+- [[Cookbook|sbtCookbook]]
+- [[Debugging your build|sbtDebugging]]
diff --git a/manual/working/commonGuide/build/BuildOverview.md b/manual/working/commonGuide/build/BuildOverview.md
new file mode 100644
index 00000000..fa63e0db
--- /dev/null
+++ b/manual/working/commonGuide/build/BuildOverview.md
@@ -0,0 +1,81 @@
+
+# Overview of the build system
+
+The Play build system uses [sbt](https://www.scala-sbt.org/), a high-performance integrated build for Scala and Java projects. Using `sbt` as our build tool brings certain requirements to play which are explained on this page.
+
+## Understanding sbt
+
+sbt functions quite differently to many traditional build tasks. Fundamentally, sbt is a task engine. Your build is represented as a tree of task dependencies that need to be executed, for example, the `compile` task depends on the `sources` task, which depends on the `sourceDirectories` task and the `sourceGenerators` task, and so on.
+
+sbt breaks typical build executions up into very fine grained tasks, and any task at any point in the tree can be arbitrarily redefined in your build. This makes sbt very powerful, but also requires a shift in thinking if you've come from other build tools that break your build up into very coarsely grained tasks.
+
+The documentation here describes Play's usage of sbt at a very high level. As you start to use sbt more in your project, it is recommended that you follow the [sbt tutorial](https://www.scala-sbt.org/0.13/tutorial/index.html) to get an understanding for how sbt fits together. Another resource that many people have found useful is [this series of blog posts](https://jazzy.id.au/2015/03/03/sbt-task-engine.html).
+
+## Play application directory structure
+
+Most people get started with Play using on of our [example templates](https://playframework.com/download#examples), or with the `sbt new` command, which generally produce a directory structure like this:
+
+- `/`: The root folder of your application
+- `/README`: A text file describing your application that will get deployed with it.
+- `/app`: Where your application code will be stored.
+- `/build.sbt`: The [sbt](https://www.scala-sbt.org/) settings that describe building your application.
+- `/conf`: Configuration files for your application
+- `/project`: Further build description information
+- `/public`: Where static, public assets for your application are stored.
+- `/test`: Where your application's test code will be stored.
+
+For now, we are going to concern ourselves with the `/build.sbt` file and the `/project` directory.
+
+> **Tip**: See the complete [[anatomy of a Play application here|Anatomy]].
+
+## The `/build.sbt` file.
+
+An sbt build file for Play generally looks something like this:
+
+@[default](code/build.sbt)
+
+The `name` line defines the name of your application and it will be the same as the name of your application's root directory, `/`. In sbt this is derived from the argument that you gave to the `sbt new` command.
+
+The `version` line provides the version of your application which is used as part of the name for the artifacts your build will produce.
+
+The `libraryDependencies` line specifies the libraries that your application depends on. You can see more details about [how to manage your dependencies in the sbt docs](https://www.scala-sbt.org/0.13/docs/Library-Management.html).
+
+Finally, you need to enable an sbt plugin on your project to "Play-ify" it. This adds support for Play-specific features such as the twirl compiler and the routes compiler, and adds the necessary Play libraries to build your project and run the server. Generally you should use one of the following Play plugins for a Play application:
+ - `PlayScala`: a standard Play Scala project.
+ - `PlayJava`: a standard Play Java project, with the [[forms|JavaForms]] module.
+ - `PlayMinimalJava`: a minimal Play Java project, without forms support.
+
+### Using scala for building
+
+sbt is also able to construct the build requirements from scala files inside your project's `project` folder. The recommended practice is to use `build.sbt` but there are times when using scala directly is required. If you find yourself, perhaps because you're migrating an older project, then here are a few useful imports:
+
+```scala
+import sbt._
+import Keys._
+import play.sbt._
+import Play.autoImport._
+import PlayKeys._
+```
+
+The line indicating `autoImport` is the correct means of importing an sbt plugin's automatically declared properties. Along the same lines, if you're importing an sbt-web plugin then you might well:
+
+```scala
+import com.typesafe.sbt.less.autoImport._
+import LessKeys._
+```
+
+## The `/project` directory
+
+Everything related to building your project is kept in the `/project` directory underneath your application directory. This is an [sbt](https://www.scala-sbt.org/) requirement. Inside that directory, there are two files:
+
+- `/project/build.properties`: This is a marker file that declares the sbt version used.
+- `/project/plugins.sbt`: sbt plugins used by the project build including Play itself.
+
+## Play plugin for sbt (`/project/plugins.sbt`)
+
+The Play console and all of its development features like live reloading are implemented via an sbt plugin. It is registered in the `/project/plugins.sbt` file:
+
+```scala
+addSbtPlugin("com.typesafe.play" % "sbt-plugin" % playVersion) // where version is the current Play version, i.e. "%PLAY_VERSION%"
+```
+> **Note**: `build.properties` and `plugins.sbt` must be manually updated when you are changing the play version.
diff --git a/manual/working/commonGuide/build/CompilationSpeed.md b/manual/working/commonGuide/build/CompilationSpeed.md
new file mode 100644
index 00000000..68cf1550
--- /dev/null
+++ b/manual/working/commonGuide/build/CompilationSpeed.md
@@ -0,0 +1,20 @@
+
+# Improving Compilation Times
+
+Compilation speed can be improved by following some guidelines that are also good engineering practice:
+
+## Use subprojects/modularize
+
+This is something like bulkheads for incremental compilation in addition to the other benefits of modularization. It minimizes the size of cycles, makes inter-dependencies explicit, and allows you to work with a subset of the code when desired. It also allows sbt to compile independent modules in parallel.
+
+## Annotate return types of public methods
+
+This makes compilation faster as it reduces the need for type inference and for accuracy helps address corner cases in incremental compilation arising from inference across source file boundaries.
+
+## Avoid large cycles between source files
+
+Cycles tend to result in larger recompilations and/or more steps. In sbt 0.13.0+ (Play 2.2+), this is less of a problem.
+
+## Minimize inheritance
+
+A public API change in a source file typically requires recompiling all descendents.
diff --git a/manual/working/commonGuide/build/PlayEnhancer.md b/manual/working/commonGuide/build/PlayEnhancer.md
new file mode 100644
index 00000000..1d94335b
--- /dev/null
+++ b/manual/working/commonGuide/build/PlayEnhancer.md
@@ -0,0 +1,52 @@
+
+# Play enhancer
+
+The [Play enhancer](https://github.com/playframework/play-enhancer) is an sbt plugin that generates getters and setters for Java beans, and rewrites the code that accesses those fields to use the getters and setters.
+
+## Motivation
+
+One common criticism of Java is that simple things require a lot of boilerplate code. One of the biggest examples of this is encapsulating fields - it is considered good practice to encapsulate the access and mutation of fields in methods, as this allows future changes such as validation and generation of the data. In Java, this means making all your fields private, and then writing getters and setters for each field, a typical overhead of 6 lines of code per field.
+
+Furthermore, many libraries, particularly libraries that use reflection to access properties of objects such as ORMs, require classes to be implemented in this way, with getters and setters for each field.
+
+The Play enhancer provides a convenient alternative to manually implementing getters and setters. It implements some post processing on the compiled byte code for your classes, this is commonly referred to as byte code enhancement. For every public field in your classes, Play will automatically generate a getter and setter, and then will rewrite the code that uses these fields to use the getters and setters instead.
+
+### Drawbacks
+
+Using byte code enhancement to generating getters and setters is not without its drawbacks however. Here are a few:
+
+* Byte code enhancement is opaque, you can't see the getters and setters that are generated, so when things go wrong, it can be hard to debug and understand what is happening. Byte code enhancement is ofter described as being "magic" for this reason.
+* Byte code enhancement can interfere with the operation of some tooling, such as IDEs, as they will be unaware of the eventual byte code that gets used. This can cause problems such as tests failing when run in an IDE because they depend on byte code enhancement, but the IDE isn't running the byte code enhancer when it compiles your source files.
+* Existing Java developers that are new to your codebase will not expect getters and setters to be generated, this can cause confusion.
+
+Whether you use the Play enhancer or not in your projects is up to you, if you do decide to use it the most important thing is that you understand what the enhancer does, and what the drawbacks may be.
+
+## Setting up
+
+To enable the byte code enhancer, simply add the following line to your `project/plugins.sbt` file:
+
+@[plugins.sbt](code/enhancer.sbt)
+
+The Play enhancer should be enabled for all your projects. If you want to disable the Play enhancer for a particular project, you can do that like so in your `build.sbt` file:
+
+@[disable-project](code/enhancer.sbt)
+
+In some situations, it may not be possible to disable the enhancer plugin, an example of this is using Play's ebean plugin, which requires the enhancer to ensure that getters and setters are generated before it does its byte code enhancement. If you don't want to generate getters and setters in that case, you can use the `playEnhancerEnabled` setting:
+
+@[disable-enhancement](code/enhancer.sbt)
+
+## Operation
+
+The enhancer looks for all fields on Java classes that:
+
+* are public
+* are non static
+* are non final
+
+For each of those fields, it will generate a getter and a setter if they don't already exist. If you wish to provide a custom getter or setter for a field, this can be done by just writing it, the Play enhancer will simply skip the generation of the getter or setter if it already exists.
+
+## Configuration
+
+If you want to control exactly which files get byte code enhanced, this can be done by configuring the `sources` task scoped to the `playEnhancerGenerateAccessors` and `playEnhancerRewriteAccessors` tasks. For example, to only enhance the java sources in the models package, you might do this:
+
+@[select-generate](code/enhancer.sbt)
diff --git a/manual/detailedTopics/build/code/aggregate.sbt b/manual/working/commonGuide/build/code/aggregate.sbt
similarity index 85%
rename from manual/detailedTopics/build/code/aggregate.sbt
rename to manual/working/commonGuide/build/code/aggregate.sbt
index 29739126..200a1846 100644
--- a/manual/detailedTopics/build/code/aggregate.sbt
+++ b/manual/working/commonGuide/build/code/aggregate.sbt
@@ -1,3 +1,7 @@
+//
+// Copyright (C) 2009-2019 Lightbend Inc.
+//
+
//#content
lazy val common: Project = (project in file("common"))
.enablePlugins(PlayScala)
diff --git a/manual/detailedTopics/build/code/build.sbt b/manual/working/commonGuide/build/code/build.sbt
similarity index 62%
rename from manual/detailedTopics/build/code/build.sbt
rename to manual/working/commonGuide/build/code/build.sbt
index 8dd14ba5..f9b828c4 100644
--- a/manual/detailedTopics/build/code/build.sbt
+++ b/manual/working/commonGuide/build/code/build.sbt
@@ -1,3 +1,7 @@
+//
+// Copyright (C) 2009-2019 Lightbend Inc.
+//
+
//#default
name := "foo"
@@ -6,8 +10,8 @@ version := "1.0-SNAPSHOT"
libraryDependencies ++= Seq(
jdbc,
anorm,
- cache
+ ehcache
)
lazy val root = (project in file(".")).enablePlugins(PlayScala)
-//#default
\ No newline at end of file
+//#default
diff --git a/manual/working/commonGuide/build/code/common.build.routes b/manual/working/commonGuide/build/code/common.build.routes
new file mode 100644
index 00000000..a351deb6
--- /dev/null
+++ b/manual/working/commonGuide/build/code/common.build.routes
@@ -0,0 +1,5 @@
+#assets-routes
+GET /index controllers.admin.HomeController.index()
+
+GET /assets/*file controllers.Assets.at(path="/public/lib/myadmin", file)
+#assets-routes
diff --git a/manual/working/commonGuide/build/code/cookbook.sbt b/manual/working/commonGuide/build/code/cookbook.sbt
new file mode 100644
index 00000000..2275618b
--- /dev/null
+++ b/manual/working/commonGuide/build/code/cookbook.sbt
@@ -0,0 +1,25 @@
+//
+// Copyright (C) 2009-2019 Lightbend Inc.
+//
+
+//#compiler-options
+scalacOptions += "-feature"
+//#compiler-options
+
+//#add-assets
+unmanagedResourceDirectories in Assets += baseDirectory.value / "pictures"
+//#add-assets
+
+//#disable-scaladoc
+sources in (Compile, doc) := Seq.empty
+publishArtifact in (Compile, packageDoc) := false
+//#disable-scaladoc
+
+//#ivy-logging
+ivyLoggingLevel := UpdateLogging.Quiet
+//#ivy-logging
+
+//#fork-parallel-test
+parallelExecution in Test := true
+fork in Test := false
+//#fork-parallel-test
diff --git a/manual/working/commonGuide/build/code/dependencies.sbt b/manual/working/commonGuide/build/code/dependencies.sbt
new file mode 100644
index 00000000..e0c5170f
--- /dev/null
+++ b/manual/working/commonGuide/build/code/dependencies.sbt
@@ -0,0 +1,36 @@
+//
+// Copyright (C) 2009-2019 Lightbend Inc.
+//
+
+//#single-dep
+libraryDependencies += "org.apache.derby" % "derby" % "10.13.1.1"
+//#single-dep
+
+//#single-dep-test
+libraryDependencies += "org.apache.derby" % "derby" % "10.13.1.1" % "test"
+//#single-dep-test
+
+//#multi-deps
+libraryDependencies ++= Seq(
+ "org.apache.derby" % "derby" % "10.13.1.1",
+ "org.hibernate" % "hibernate-entitymanager" % "5.2.10.Final"
+)
+//#multi-deps
+
+//#explicit-scala-version-dep
+libraryDependencies += "org.scala-stm" % "scala-stm_2.11" % "0.8"
+//#explicit-scala-version-dep
+
+//#auto-scala-version-dep
+libraryDependencies += "org.scala-stm" %% "scala-stm" % "0.8"
+//#auto-scala-version-dep
+
+//#resolver
+resolvers += "sonatype snapshots".at("https://oss.sonatype.org/content/repositories/snapshots/")
+//#resolver
+
+//#local-maven-repos
+resolvers += (
+ "Local Maven Repository".at(s"file:///${Path.userHome.absolutePath}/.m2/repository")
+)
+//#local-maven-repos
diff --git a/manual/detailedTopics/build/code/enhancer.sbt b/manual/working/commonGuide/build/code/enhancer.sbt
similarity index 73%
rename from manual/detailedTopics/build/code/enhancer.sbt
rename to manual/working/commonGuide/build/code/enhancer.sbt
index 4fee31cd..569678ac 100644
--- a/manual/detailedTopics/build/code/enhancer.sbt
+++ b/manual/working/commonGuide/build/code/enhancer.sbt
@@ -1,5 +1,9 @@
+//
+// Copyright (C) 2009-2019 Lightbend Inc.
+//
+
//#plugins.sbt
-addSbtPlugin("com.typesafe.sbt" % "sbt-play-enhancer" % "1.1.0")
+addSbtPlugin("com.typesafe.sbt" % "sbt-play-enhancer" % "1.2.2")
//#plugins.sbt
//#disable-project
diff --git a/manual/working/commonGuide/build/code/javaguide/common/build/controllers/AssetsBuilder.java b/manual/working/commonGuide/build/code/javaguide/common/build/controllers/AssetsBuilder.java
new file mode 100644
index 00000000..0c4f6f0d
--- /dev/null
+++ b/manual/working/commonGuide/build/code/javaguide/common/build/controllers/AssetsBuilder.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+// #assets-builder
+// ###replace: package controllers.admin;
+package javaguide.common.build.controllers;
+
+import play.api.mvc.*;
+import controllers.AssetsMetadata;
+import play.api.http.HttpErrorHandler;
+
+import javax.inject.Inject;
+
+// ###replace: public class AssetsBuilder extends controllers.Assets {
+class Assets extends controllers.Assets {
+
+ @Inject
+ public Assets(HttpErrorHandler errorHandler, AssetsMetadata meta) {
+ super(errorHandler, meta);
+ }
+
+ public Action at(String path, String file) {
+ boolean aggressiveCaching = true;
+ return super.at(path, file, aggressiveCaching);
+ }
+}
+// #assets-builder
diff --git a/manual/working/commonGuide/build/code/javaguide/common/build/controllers/HomeController.java b/manual/working/commonGuide/build/code/javaguide/common/build/controllers/HomeController.java
new file mode 100644
index 00000000..b334176d
--- /dev/null
+++ b/manual/working/commonGuide/build/code/javaguide/common/build/controllers/HomeController.java
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+// ###replace: package controllers.admin;
+package javaguide.common.build.controllers;
+
+import play.mvc.Controller;
+import play.mvc.Result;
+
+public class HomeController extends Controller {
+ public Result index() {
+ return ok("admin");
+ }
+}
diff --git a/manual/working/commonGuide/build/code/runhook.sbt b/manual/working/commonGuide/build/code/runhook.sbt
new file mode 100644
index 00000000..b66171b8
--- /dev/null
+++ b/manual/working/commonGuide/build/code/runhook.sbt
@@ -0,0 +1,66 @@
+//
+// Copyright (C) 2009-2019 Lightbend Inc.
+//
+
+// You can't define objects at the root level of an sbt file, so we do it inside a def
+def Grunt(base: File) = {
+ //#grunt-before-started
+ import play.sbt.PlayRunHook
+ import sbt._
+ import scala.sys.process.Process
+
+ object Grunt {
+ def apply(base: File): PlayRunHook = {
+
+ object GruntProcess extends PlayRunHook {
+
+ override def beforeStarted(): Unit = {
+ Process("grunt dist", base).run
+ }
+ }
+
+ GruntProcess
+ }
+ }
+ //#grunt-before-started
+ Grunt(base)
+}
+
+//#grunt-build-sbt
+PlayKeys.playRunHooks += Grunt(baseDirectory.value)
+//#grunt-build-sbt
+
+def Grunt2(base: File) = {
+ //#grunt-watch
+ import play.sbt.PlayRunHook
+ import sbt._
+ import java.net.InetSocketAddress
+ import scala.sys.process.Process
+
+ object Grunt {
+ def apply(base: File): PlayRunHook = {
+
+ object GruntProcess extends PlayRunHook {
+
+ var watchProcess: Option[Process] = None
+
+ override def beforeStarted(): Unit = {
+ Process("grunt dist", base).run
+ }
+
+ override def afterStarted(addr: InetSocketAddress): Unit = {
+ watchProcess = Some(Process("grunt watch", base).run)
+ }
+
+ override def afterStopped(): Unit = {
+ watchProcess.map(p => p.destroy())
+ watchProcess = None
+ }
+ }
+
+ GruntProcess
+ }
+ }
+ //#grunt-watch
+ Grunt(base)
+}
diff --git a/manual/working/commonGuide/build/code/scalaguide/common/build/controllers/SubProjectAssets.scala b/manual/working/commonGuide/build/code/scalaguide/common/build/controllers/SubProjectAssets.scala
new file mode 100644
index 00000000..f6c44fbe
--- /dev/null
+++ b/manual/working/commonGuide/build/code/scalaguide/common/build/controllers/SubProjectAssets.scala
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package scalaguide.common.build
+
+package object controllers {
+ type AssetsBuilder = _root_.controllers.AssetsBuilder
+ type Assets = _root_.controllers.Assets
+}
diff --git a/manual/working/commonGuide/build/code/scalaguide/common/build/controllers/SubProjectsAssetsBuilder.scala b/manual/working/commonGuide/build/code/scalaguide/common/build/controllers/SubProjectsAssetsBuilder.scala
new file mode 100644
index 00000000..1ab0b1c7
--- /dev/null
+++ b/manual/working/commonGuide/build/code/scalaguide/common/build/controllers/SubProjectsAssetsBuilder.scala
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package common.build.controllers {
+
+ //#assets-builder
+ import javax.inject._
+
+ import play.api.http.HttpErrorHandler
+
+ class Assets @Inject()(
+ errorHandler: HttpErrorHandler,
+ assetsMetadata: controllers.AssetsMetadata
+ ) extends controllers.AssetsBuilder(errorHandler, assetsMetadata)
+ //#assets-builder
+
+ package admin {
+ //#admin-home-controller
+ //###insert: package controllers.admin
+
+ import play.api.mvc._
+ import javax.inject.Inject
+
+ class HomeController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {
+
+ def index = Action { implicit request =>
+ Ok("admin")
+ }
+ }
+ //#admin-home-controller
+ }
+}
diff --git a/manual/detailedTopics/build/images/ivy-report.png b/manual/working/commonGuide/build/images/ivy-report.png
similarity index 100%
rename from manual/detailedTopics/build/images/ivy-report.png
rename to manual/working/commonGuide/build/images/ivy-report.png
diff --git a/manual/working/commonGuide/build/index.toc b/manual/working/commonGuide/build/index.toc
new file mode 100644
index 00000000..ddbf4739
--- /dev/null
+++ b/manual/working/commonGuide/build/index.toc
@@ -0,0 +1,10 @@
+Build:Contents
+BuildOverview:Overview of the build system
+sbtSettings:About sbt settings
+sbtDependencies:Manage application dependencies
+sbtSubProjects:Working with sub-projects
+PlayEnhancer:Play enhancer
+AggregatingReverseRouters:Aggregating reverse routers
+CompilationSpeed:Improving Compilation Times
+sbtCookbook:Cookbook
+sbtDebugging:Debugging your build
diff --git a/manual/working/commonGuide/build/sbtCookbook.md b/manual/working/commonGuide/build/sbtCookbook.md
new file mode 100644
index 00000000..d585e369
--- /dev/null
+++ b/manual/working/commonGuide/build/sbtCookbook.md
@@ -0,0 +1,72 @@
+
+# sbt Cookbook
+
+## Hooking into Play's dev mode
+
+When Play runs in dev mode, that is, when using `sbt run`, it's often useful to hook into this to start up additional processes that are required for development. This can be done by defining a `PlayRunHook`, which is a trait with the following methods:
+
+ * `beforeStarted(): Unit` - called before the play application is started, but after all "before run" tasks have been completed.
+ * `afterStarted(addr: InetSocketAddress): Unit` - called after the play application has been started.
+ * `afterStopped(): Unit` - called after the play process has been stopped.
+
+Now let's say you want to build a Web application with `grunt` before the application is started. First, you need to create a Scala object in the `project/` directory to extend `PlayRunHook`. Let's name it `Grunt.scala`:
+
+@[grunt-before-started](code/runhook.sbt)
+
+Now you can register this hook in `build.sbt`:
+
+@[grunt-build-sbt](code/runhook.sbt)
+
+This will execute the `grunt dist` command in `baseDirectory` before the application is started whenever you run `sbt run`.
+
+Now we want to modify our run hook to execute the `grunt watch` command to observe changes and rebuild the Web application when they happen, so we'll modify the `Grunt.scala` file we created before:
+
+@[grunt-watch](code/runhook.sbt)
+
+Now when the application is started using `sbt run`, `grunt watch` will be executed to rerun the grunt build whenever files change.
+
+## Add compiler options
+
+For example, you may want to add the feature flag to have details on feature warnings:
+
+```
+[info] Compiling 1 Scala source to ~/target/scala-2.10/classes...
+[warn] there were 1 feature warnings; re-run with -feature for details
+```
+
+Simply add `-feature` to the `scalacOptions` attribute:
+
+@[compiler-options](code/cookbook.sbt)
+
+## Add additional asset directory
+
+For example you can add the `pictures` folder to be included as an additional asset directory:
+
+@[add-assets](code/cookbook.sbt)
+
+This will allow you to use `routes.Assets.at` with this folder.
+
+## Disable documentation
+
+To speed up compilation you can disable documentation generation:
+
+@[disable-scaladoc](code/cookbook.sbt)
+
+The first line will disable documentation generation and the second one will avoid to publish the documentation artifact.
+
+## Configure ivy logging level
+
+By default `ivyLoggingLevel` is set on `UpdateLogging.DownloadOnly`. You can change this value with:
+
+ * `UpdateLogging.Quiet` only displays errors
+ * `UpdateLogging.Full` logs the most
+
+For example if you want to only display errors:
+
+@[ivy-logging](code/cookbook.sbt)
+
+## Fork and parallel execution in test
+
+By default parallel execution is disabled and fork is enabled. You can change this behavior by setting `parallelExecution in Test` and/or `fork in Test`:
+
+@[fork-parallel-test](code/cookbook.sbt)
diff --git a/manual/detailedTopics/build/SBTDebugging.md b/manual/working/commonGuide/build/sbtDebugging.md
similarity index 50%
rename from manual/detailedTopics/build/SBTDebugging.md
rename to manual/working/commonGuide/build/sbtDebugging.md
index 9929c5cb..8d083dfc 100644
--- a/manual/detailedTopics/build/SBTDebugging.md
+++ b/manual/working/commonGuide/build/sbtDebugging.md
@@ -1,55 +1,25 @@
-
-
# Debugging your build
--->
-# ビルドをデバッグする
-
-sbt を思い通りに動かすのに手こずっているのであれば、ビルドのデバッグを支援するために sbt が提供している組み込みユーティリティをいくつか使う必要があるのかもしれません。
-
-## 依存性のデバッグ
-
-sbt はデフォルトで、どの依存性が他の依存性に取り込まれているかを示す依存性ツリー、そして複数の依存性が要求されたときに sbt がどのようにしてバージョンを選択しているかを表示するコンフリクト解決テーブルを含む、すべての依存性のレポートを生成します。
-
-このレポートは、XSL をサポートしているブラウザでは XML から HTML に変換できるようにする XSL スタイルシートを伴った XML ファイルとして生成されます。これをサポートしているブラウザには Firefox と Safari が含まれますが、注目すべきことに Chrome が含まれていません。
-
-このレポートはプロジェクトの `target/resolution-cache/reports` ディレクトリ内にプロジェクトのスコープごとに生成されており、例えば `com.example-my-first-app_2.11-compile.xml` のように `organization-projectId_scalaVersion-scope.xml` という名前が付けられています。このレポートは Firefox で開くと以下のように見えます:
+The reports can be found in the `target/scala-2.12/resolution-cache/reports/` directory of your project, one is generated for each scope in your project, and are named `organization-projectId_scalaVersion-scope.xml`, for example, `com.example-my-first-app_2.11-compile.xml`. When opened in Firefox, this report looks something like this:
[[images/ivy-report.png]]
-
-## 設定のデバッグ
-
-sbt は、ビルドを理解し、なにかおかしくなったところを解決するために使うことのできる便利なコマンドをいくつか提供しています。
-
-### show コマンド
-
-show コマンドはあらゆる sbt タスクの戻り値を表示します。例えば、あるソースファイルがコンパイルされるかどうかよく分からない場合、`show sources` を実行して sbt がそれをソースに含めているかどうか見ることができます:
```
[my-first-app] $ show sources
@@ -61,15 +31,9 @@ show コマンドはあらゆる sbt タスクの戻り値を表示します。
my-first-app/target/scala-2.11/src_managed/main/controllers/routes.java)
```
-
-上記の出力はスクリーンにぴったり収まるように整形されていますが、実行したタスクが長いリストを返す場合は、その内容を理解するためにエディタにコピーする必要があるかもしれません。
-
-例えば `test:sources` や `compile:sources` のように、タスクに特定のスコープを指定したり、`my-project/compile:sources` のように特定のプロジェクトを指定することもできます。また、あるタスクが他のタスクのスコープとなっている別の場合は、そのスコープを指定することもできます。例えばプロジェクトの jar ファイルにパッケージされるものをすべて表示するには、`packageBin` タスクをスコープとする `mappings` タスクを表示します:
```
[my-first-app] $ show compile:packageBin::mappings
@@ -79,15 +43,9 @@ You can also specify a task a particular scope, eg `test:sources` or `compile:so
...
```
-
-### inspect コマンド
-
-inspect コマンドは、タスクが何に依存しているか、何から依存されているか、どこに定義されているか、などの詳細情報を提供します。これは `show` コマンドと同じように使うことができます:
```
[my-first-app] $ inspect managedSources
@@ -105,20 +63,11 @@ inspect コマンドは、タスクが何に依存しているか、何から依
...
```
-
-ここでは `managedSources` コマンドを調査し、このタスクはファイルのシーケンスを提供すること、`Sources generated by the build` という説明文を持つことが分かります。`sourceGenerators` タスクに依存していること、`sources` タスクから依存されていることも確認できます。どこに定義されているかを確認することもできて、この場合は sbt のデフォルトタスク定義の 185 行目です。
-
-### inspect tree コマンド
-
-inspect tree コマンドは、あるタスクのタスクツリー全体を表示します。`unmanagedSources` タスクのタスクツリーを調査した場合、以下のように表示されます:
```
[my-first-app] $ inspect tree unmanagedSources
@@ -138,25 +87,13 @@ inspect tree コマンドは、あるタスクのタスクツリー全体を表
[info] +-*/*:excludeFilter = sbt.HiddenFileFilter$@49e479da
```
-
-ここでは、どのファイルを含める、あるいは除外するかを判断するフィルタを含め、プロジェクト内にあるソースを発見するために sbt が使うタスクツリー全体が表示されています。`inspect tree` コマンドは、ビルドのある部分がどのように構築されていてのかよく分からず、それらがどのように組み合わさるのかを解明したい場合に特に便利で、これによりさらに詳しく調べていくことができます。
-
-## インクリメンタルコンパイルのデバッグ
-
-人々が Play に持っている共通の問題は、期待していないときに Play が再コンパイルし、再ロードすることです。多くの場合、これはソースジェネレータまたは IDE がなんらかの事情で Play クラスパスの要素を更新し、再ロードを強制することで引き起こされます。このような問題を解決するために、compile タスクのデバッグログを見ることができます。sbt はタスクを実行すると、それを表示するしないに関わらずログ出力をすべてキャプチャするので、必要な場合は後から調査することができます。これは `last` コマンドを使って調査することができます。
-
-さて、ここで `compile` を実行して、あるファイルを再コンパイルする必要があったとしましょう:
```
[my-first-app] $ compile
@@ -164,10 +101,7 @@ So, let's say you `compile`, and a file needs to be recompiled:
[success] Total time: 1 s, completed 07/04/2015 1:28:43 PM
```
-
-`last compile` を実行すると、compile コマンドの実行中に起こったことの完全なデバッグログを取得できます。大量のダンプが出力されますが、興味があるのは以下に示す最初の部分だけです:
```
[my-first-app] $ last compile
@@ -187,7 +121,4 @@ You can get a full debug log of what happened during the compile command by runn
[debug] external source: Set()
```
-
-これは、`my-first-app/app/controllers/Application.scala` が変更されたために再コンパイルが引き起こされたことを伝えています。
\ No newline at end of file
diff --git a/manual/working/commonGuide/build/sbtDependencies.md b/manual/working/commonGuide/build/sbtDependencies.md
new file mode 100644
index 00000000..9e0b0ccb
--- /dev/null
+++ b/manual/working/commonGuide/build/sbtDependencies.md
@@ -0,0 +1,64 @@
+
+# Managing library dependencies
+
+> **Note:** Some sections of this page were copied from the sbt manual, specifically from the [Library Dependencies](https://www.scala-sbt.org/0.13/docs/Library-Dependencies.html) page. You can refer to that page for a more detailed and updated version of the information here.
+
+## Unmanaged dependencies
+
+Most people end up using managed dependencies - which allows for fine-grained control, but unmanaged dependencies can be simpler when starting out.
+
+Unmanaged dependencies work like this: create a `lib/` directory in the root of your project and then add jar files to that directory. They will automatically be added to the application classpath. There's not much else to it.
+
+There's nothing to add to `build.sbt` to use unmanaged dependencies, although you could change a configuration key if you'd like to use a directory different than `lib`.
+
+## Managed dependencies
+
+Play uses [Apache Ivy](http://ant.apache.org/ivy/) (via sbt) to implement managed dependencies, so if you're familiar with Maven or Ivy, you are already used to managed dependencies.
+
+Most of the time you can simply list your dependencies in the `build.sbt` file.
+
+Declaring a dependency looks like this (defining `group`, `artifact` and `revision`):
+
+@[single-dep](code/dependencies.sbt)
+
+Or like this, with an optional `configuration`:
+
+@[single-dep-test](code/dependencies.sbt)
+
+Multiple dependencies can be added either by multiple declarations like the above, or you can provide a Scala sequence:
+
+@[multi-deps](code/dependencies.sbt)
+
+Of course, sbt (via Ivy) has to know where to download the module. If your module is in one of the default repositories sbt comes with then this will just work.
+
+### Getting the right Scala version with `%%`
+
+If you use `groupID %% artifactID % revision` rather than `groupID % artifactID % revision` (the difference is the double `%%` after the `groupID`), sbt will add your project's Scala version to the artifact name. This is just a shortcut. You could write this without the `%%`:
+
+@[explicit-scala-version-dep](code/dependencies.sbt)
+
+Assuming the `scalaVersion` for your build is `2.11.1`, the following is identical (note the double `%%` after `"org.scala-tools"`):
+
+@[auto-scala-version-dep](code/dependencies.sbt)
+
+The idea is that many dependencies are compiled for multiple Scala versions, and you'd like to get the one that matches your project to ensure binary compatibility.
+
+### Resolvers
+
+sbt uses the standard Maven2 repository and the Typesafe Releases () repositories by default. If your dependency isn't on one of the default repositories, you'll have to add a resolver to help Ivy find it.
+
+Use the `resolvers` setting key to add your own resolver. For example:
+
+@[resolver](code/dependencies.sbt)
+
+sbt can search your local Maven repository if you add it as a repository:
+
+@[local-maven-repos](code/dependencies.sbt)
+
+## Handling conflicts between dependencies
+
+sbt has extensive documentation about how to manage conflict between your dependencies:
+
+[sbt: Dependencies Conflict Management](https://www.scala-sbt.org/0.13/docs/Library-Management.html#Conflict+Management)
+
+You can also use [sbt-dependency-graph](https://github.com/jrudolph/sbt-dependency-graph) to have a better visualization of your dependency tree. See also our page about [[debugging sbt|sbtDebugging]] common problems.
diff --git a/manual/working/commonGuide/build/sbtSettings.md b/manual/working/commonGuide/build/sbtSettings.md
new file mode 100644
index 00000000..6eb211d8
--- /dev/null
+++ b/manual/working/commonGuide/build/sbtSettings.md
@@ -0,0 +1,20 @@
+
+# About sbt Settings
+
+## About sbt settings
+
+The `build.sbt` file defines settings for your project. You can also define your own custom settings for your project, as described in the [sbt documentation](https://www.scala-sbt.org). In particular, it helps to be familiar with the [settings](https://www.scala-sbt.org/release/docs/Getting-Started/More-About-Settings) in sbt.
+
+To set a basic setting, use the `:=` operator:
+
+```scala
+confDirectory := "myConfFolder"
+```
+
+## Default settings for Java applications
+
+Play defines a default set of settings suitable for Java-based applications. To enable them add the `PlayJava` plugin via your project's enablePlugins method. These settings mostly define the default imports for generated templates e.g. importing `java.lang.*` so types like `Long` are the Java ones by default instead of the Scala ones. `play.Project.playJavaSettings` also imports `java.util.*` so that the default collection library will be the Java one.
+
+## Default settings for Scala applications
+
+Play defines a default set of settings suitable for Scala-based applications. To enable them add the `PlayScala` plugin via your project's enablePlugins method. These default settings define the default imports for generated templates (such as internationalized messages, and core APIs).
diff --git a/manual/working/commonGuide/build/sbtSubProjects.md b/manual/working/commonGuide/build/sbtSubProjects.md
new file mode 100644
index 00000000..84055358
--- /dev/null
+++ b/manual/working/commonGuide/build/sbtSubProjects.md
@@ -0,0 +1,248 @@
+
+# Working with sub-projects
+
+A complex project is not necessarily composed of a single Play application. You may want to split a large project into several smaller applications, or even extract some logic into a standard Java or Scala library that has nothing to do with a Play application.
+
+It will be helpful to read the [sbt documentation on multi-project builds](https://www.scala-sbt.org/release/docs/Getting-Started/Multi-Project). Sub-projects can be fully defined in the parent project's build file, although here we put sub-projects' settings in their own build file.
+
+## Adding a simple library sub-project
+
+You can make your application depend on a simple library project. Just add another sbt project definition in your `build.sbt` file:
+
+```
+name := "my-first-application"
+
+version := "1.0"
+
+lazy val myFirstApplication = (project in file("."))
+ .enablePlugins(PlayScala)
+ .aggregate(myLibrary)
+ .dependsOn(myLibrary)
+
+lazy val myLibrary = project
+```
+
+The lowercased `project` on the last line is a Scala Macro which will use the name of the val it is being assigned to in order to determine the project's name and folder.
+
+The `myFirstApplication` project declares the base project. If you don't have any sub projects, this is already implied, however when declaring sub projects, it's usually required to declare it so that you can ensure that it aggregates (that is, runs things like compile/test etc on the sub projects when run in the base project) and depends on (that is, adds the sub projects to the main projects classpath) the sub projects.
+
+The above example defines a sub-project in the application’s `myLibrary` folder. This sub-project is a standard sbt project, using the default layout:
+
+```
+myProject
+ └ build.sbt
+ └ app
+ └ conf
+ └ public
+ └ myLibrary
+ └ build.sbt
+ └ src
+ └ main
+ └ java
+ └ scala
+```
+
+`myLibrary` has its own `build.sbt` file, this is where it can declare its own settings, dependencies etc.
+
+When you have a sub-project enabled in your build, you can focus on this project and compile, test or run it individually. Just use the `projects` command in the Play console prompt to display all projects:
+
+```
+[my-first-application] $ projects
+[info] In file:/Volumes/Data/gbo/myFirstApp/
+[info] * my-first-application
+[info] my-library
+```
+
+The default project is the one whose variable name comes first alphabetically. You may make your main project by making its variable name aaaMain. To change the current project use the `project` command:
+
+```
+[my-first-application] $ project my-library
+[info] Set current project to my-library
+>
+```
+
+When you run your Play application in dev mode, the dependent projects are automatically recompiled, and if something cannot compile you will see the result in your browser:
+
+[[subprojectError.png]]
+
+## Sharing common variables and code
+
+If you want your sub projects and root projects to share some common settings or code, then these can be placed in a Scala file in the `project` directory of the root project. For example, in `project/Common.scala` you might have:
+
+```scala
+import sbt._
+import Keys._
+
+object Common {
+ val settings: Seq[Setting[_]] = Seq(
+ organization := "com.example",
+ version := "1.2.3-SNAPSHOT"
+ )
+
+ val fooDependency = "com.foo" %% "foo" % "2.4"
+}
+```
+
+Then in each of your `build.sbt` files, you can reference anything declared in the file:
+
+```scala
+name := "my-sub-module"
+
+Common.settings
+
+libraryDependencies += Common.fooDependency
+```
+
+One thing to note is that if you have a mix of Play and non-Play projects, you may need to share Play configuration explicitly. For example, you may want to share the `InjectedRoutesGenerator` and specs2 for every Play project:
+
+```scala
+object Common {
+
+ val playSettings = settings ++ Seq(
+ routesGenerator := InjectedRoutesGenerator,
+ libraryDependencies += specs2 % Test,
+ resolvers += "scalaz-bintray" at "https://dl.bintray.com/scalaz/releases"
+ )
+}
+```
+
+And in the sub-project's `build.sbt` file, you would have the following:
+
+```scala
+Common.playSettings
+```
+
+## Splitting your web application into several parts
+
+As a Play application is just a standard sbt project with a default configuration, it can depend on another Play application. You can make any sub module a Play application by adding the `PlayJava` or `PlayScala` plugins, depending on whether your project is a Java or Scala project, in its corresponding `build.sbt` file.
+
+> **Note:** In order to avoid naming collision, make sure your controllers, including the Assets controller in your subprojects are using a different name space than the main project. For example, controllers in the `admin` module should have the fully qualified package name of `admin.MyController`.
+
+## Splitting the route file
+
+It's also possible to split the route file into smaller pieces. This is a very handy feature if you want to create a robust, reusable multi-module play application.
+
+### Consider the following build configuration
+
+`build.sbt`:
+
+```scala
+name := "myproject"
+
+lazy val admin = (project in file("modules/admin")).enablePlugins(PlayScala)
+
+lazy val main = (project in file("."))
+ .enablePlugins(PlayScala).dependsOn(admin).aggregate(admin)
+```
+
+`modules/admin/build.sbt`
+
+```scala
+name := "myadmin"
+
+libraryDependencies ++= Seq(
+ "mysql" % "mysql-connector-java" % "5.1.41",
+ jdbc,
+ anorm
+)
+```
+
+### Project structure
+
+```
+build.sbt
+app
+ └ controllers
+ └ models
+ └ views
+conf
+ └ application.conf
+ └ routes
+modules
+ └ admin
+ └ build.sbt
+ └ conf
+ └ admin.routes
+ └ app
+ └ controllers
+ └ models
+ └ views
+project
+ └ build.properties
+ └ plugins.sbt
+```
+
+> **Note:** Configuration and route file names must be unique in the whole project structure. Particularly, there must be only one `application.conf` file and only one `routes` file. To define additional routes or configuration in sub-projects, use sub-project-specific names. For instance, the route file in `admin` is called `admin.routes`. To use a specific set of settings in development mode for a sub project, it would be even better to put these settings into the build file, e.g. `PlayKeys.devSettings += ("play.http.router", "admin.Routes")`.
+
+`conf/routes`:
+
+```
+GET /index controllers.HomeController.index()
+
+-> /admin admin.Routes
+
+GET /assets/*file controllers.Assets.at(path="/public", file)
+```
+
+`modules/admin/conf/admin.routes`:
+
+@[assets-routes](code/common.build.routes)
+
+> **Note:** Resources are served from a unique classloader, and thus resource path must be relative from project classpath root.
+> Subprojects resources are generated in `target/web/public/main/lib/{module-name}`, so the resources are accessible from `/public/lib/{module-name}` when using `play.api.Application#resources(uri)` method, which is what the `Assets.at` method does.
+
+### Assets and controller classes should be all defined in the `controllers.admin` package
+
+Java
+: @[assets-builder](code/javaguide/common/build/controllers/AssetsBuilder.java)
+
+Scala
+: @[assets-builder](code/scalaguide/common/build/controllers/SubProjectsAssetsBuilder.scala)
+
+And a controller:
+
+Java
+: @[](code/javaguide/common/build/controllers/HomeController.java)
+
+Scala
+: @[admin-home-controller](code/scalaguide/common/build/controllers/SubProjectsAssetsBuilder.scala)
+
+
+### Reverse routing in ```admin```
+
+in case of a regular controller call:
+
+
+```
+controllers.admin.routes.HomeController.index
+```
+
+and for `Assets`:
+
+```
+controllers.admin.routes.Assets.at("...")
+```
+
+### Through the browser
+
+```
+http://localhost:9000/index
+```
+
+triggers
+
+```
+controllers.HomeController.index
+```
+
+and
+
+```
+http://localhost:9000/admin/index
+```
+
+triggers
+
+```
+controllers.admin.HomeController.index
+```
diff --git a/manual/detailedTopics/build/subprojectError.png b/manual/working/commonGuide/build/subprojectError.png
similarity index 100%
rename from manual/detailedTopics/build/subprojectError.png
rename to manual/working/commonGuide/build/subprojectError.png
diff --git a/manual/working/commonGuide/configuration/ApplicationSecret.md b/manual/working/commonGuide/configuration/ApplicationSecret.md
new file mode 100644
index 00000000..7f19ecd1
--- /dev/null
+++ b/manual/working/commonGuide/configuration/ApplicationSecret.md
@@ -0,0 +1,74 @@
+
+# The Application Secret
+
+Play uses a secret key for a number of things, including:
+
+* Signing session cookies and CSRF tokens
+* Built in encryption utilities
+
+It is configured in `application.conf`, with the property name `play.http.secret.key`, and defaults to `changeme`. As the default suggests, it should be changed for production.
+
+> When started in prod mode, if Play finds that the secret is not set, or if it is set to `changeme`, Play will throw an error.
+
+## Best practices
+
+Anyone that can get access to the secret will be able to generate any session they please, effectively allowing them to log in to your system as any user they please. Hence it is strongly recommended that you do not check your application secret into source control. Rather, it should be configured on your production server. This means that it is considered bad practice to put the production application secret in `application.conf`.
+
+One way of configuring the application secret on a production server is to pass it as a system property to your start script. For example:
+
+```bash
+/path/to/yourapp/bin/yourapp -Dplay.http.secret.key='QCY?tAnfk?aZ?iwrNwnxIlR6CTf:G3gf:90Latabg@5241AB`R5W:1uDFN];Ik@n'
+```
+
+This approach is very simple, and we will use this approach in the Play documentation on running your app in production mode as a reminder that the application secret needs to be set. In some environments however, placing secrets in command line arguments is not considered good practice. There are two ways to address this.
+
+### Environment variables
+
+The first is to place the application secret in an environment variable. In this case, we recommend you place the following configuration in your `application.conf` file:
+
+ play.http.secret.key="changeme"
+ play.http.secret.key=${?APPLICATION_SECRET}
+
+The second line in that configuration sets the secret to come from an environment variable called `APPLICATION_SECRET` if such an environment variable is set, otherwise, it leaves the secret unchanged from the previous line.
+
+This approach works particularly well for cloud based deployment scenarios, where the normal practice is to set passwords and other secrets via environment variables that can be configured through the API for that cloud provider.
+
+### Production configuration file
+
+Another approach is to create a `production.conf` file that lives on the server, and includes `application.conf`, but also overrides any sensitive configuration, such as the application secret and passwords.
+
+For example:
+
+ include "application"
+
+ play.http.secret.key="QCY?tAnfk?aZ?iwrNwnxIlR6CTf:G3gf:90Latabg@5241AB`R5W:1uDFN];Ik@n"
+
+Then you can start Play with:
+
+```bash
+/path/to/yourapp/bin/yourapp -Dconfig.file=/path/to/production.conf
+```
+
+## Generating an application secret
+
+Play provides a utility that you can use to generate a new secret. Run `playGenerateSecret` in the Play console. This will generate a new secret that you can use in your application. For example:
+
+```
+[my-first-app] $ playGenerateSecret
+[info] Generated new secret: QCYtAnfkaZiwrNwnxIlR6CTfG3gf90Latabg5241ABR5W1uDFNIkn
+[success] Total time: 0 s, completed 28/03/2014 2:26:09 PM
+```
+
+## Updating the application secret in application.conf
+
+Play also provides a convenient utility for updating the secret in `application.conf`, should you want to have a particular secret configured for development or test servers. This is often useful when you have encrypted data using the application secret, and you want to ensure that the same secret is used every time the application is run in dev mode.
+
+To update the secret in `application.conf`, run `playUpdateSecret` in the Play console:
+
+```
+[my-first-app] $ playUpdateSecret
+[info] Generated new secret: B4FvQWnTp718vr6AHyvdGlrHBGNcvuM4y3jUeRCgXxIwBZIbt
+[info] Updating application secret in /Users/jroper/tmp/my-first-app/conf/application.conf
+[info] Replacing old application secret: play.http.secret.key="changeme"
+[success] Total time: 0 s, completed 28/03/2014 2:36:54 PM
+```
diff --git a/manual/working/commonGuide/configuration/ConfigFile.md b/manual/working/commonGuide/configuration/ConfigFile.md
new file mode 100644
index 00000000..62be519c
--- /dev/null
+++ b/manual/working/commonGuide/configuration/ConfigFile.md
@@ -0,0 +1,430 @@
+
+# Configuration file syntax and features
+
+> The configuration file used by Play is based on the [Typesafe config library](https://github.com/typesafehub/config).
+
+The configuration file of a Play application must be defined in `conf/application.conf`. It uses the [HOCON format](https://github.com/typesafehub/config/blob/master/HOCON.md).
+
+As well as the `application.conf` file, configuration comes from a couple of other places.
+
+* Default settings are loaded from any `reference.conf` files found on the classpath. Most Play JARs include a `reference.conf` file with default settings. Settings in `application.conf` will override settings in `reference.conf` files.
+* It's also possible to set configuration using system properties. System properties override `application.conf` settings.
+
+The idiomatic way to use Config is to to have all configuration keys defined somewhere, either in `reference.conf` or `application.conf`. If the key does not have a reasonable default value, it is usually set to `null` to signify "no value".
+
+## Specifying an alternative configuration file
+
+At runtime, the default `application.conf` is loaded from the classpath. System properties can be used to force a different config source:
+
+* `config.resource` specifies a resource name including the extension, i.e. `application.conf` and not just `application`
+* `config.file` specifies a filesystem path, again it should include the extension, not be a basename
+
+These system properties specify a replacement for `application.conf`, not an addition. If you still want to use some values from the `application.conf` file then you can include the `application.conf` in your other `.conf` file by writing `include "application"` at the top of that file. After you've included the `application.conf`'s settings in your new `.conf` file you can then specify any settings that you want override.
+
+## Using from your controller
+
+The configuration can be available in your controller (or your component), to use the default settings or your custom one, thanks to Dependency Injection (in [[Scala|ScalaDependencyInjection]] or in [[Java|JavaDependencyInjection]]).
+
+Scala
+: @[dependency-injection](code/Configuration.scala)
+
+Java
+: @[dependency-injection](code/javaguide/configuration/MyController.java)
+
+## Using with Akka
+
+Akka will use the same configuration file as the one defined for your Play application. Meaning that you can configure anything in Akka in the `application.conf` file. In Play, Akka reads its settings from within the `play.akka` setting, not from the `akka` setting.
+
+## Using with the `run` command
+
+There are a couple of special things to know about configuration when running your application with the `run` command.
+
+### Extra `devSettings`
+
+You can configure extra settings for the `run` command in your `build.sbt`. These settings won't be used when you deploy your application.
+
+```
+PlayKeys.devSettings += "play.server.http.port" -> "8080"
+```
+
+### HTTP server settings in `application.conf`
+
+In `run` mode the HTTP server part of Play starts before the application has been compiled. This means that the HTTP server cannot access the `application.conf` file when it starts. If you want to override HTTP server settings while using the `run` command you cannot use the `application.conf` file. Instead, you need to either use system properties or the `devSettings` setting shown above. An example of a server setting is the HTTP port. Other server settings can be seen [[here|ProductionConfiguration#Server-configuration-options]].
+
+```
+> run -Dhttp.port=1234
+```
+
+There is also a specific *namespace* if you need to customize Akka configuration for development mode (the mode used with `run` command). You need to prefix your configuration in `PlayKeys.devSettings` with `play.akka.dev-mode`, for example:
+
+@[prefix-with-play-akka-dev-mode](code/build.sbt)
+
+This is specially useful if there is some conflict between the Akka ActorSystem used to run the development server and the ActorSystem used by the application itself.
+
+## HOCON Syntax
+
+HOCON has similarities to JSON; you can find the JSON spec at of course.
+
+### Unchanged from JSON
+
+ - files must be valid UTF-8
+ - quoted strings are in the same format as JSON strings
+ - values have possible types: string, number, object, array, boolean, null
+ - allowed number formats matches JSON; as in JSON, some possible
+ floating-point values are not represented, such as `NaN`
+
+### Comments
+
+Anything between `//` or `#` and the next newline is considered a comment and ignored, unless the `//` or `#` is inside a quoted string.
+
+### Omit root braces
+
+JSON documents must have an array or object at the root. Empty files are invalid documents, as are files containing only a non-array non-object value such as a string.
+
+In HOCON, if the file does not begin with a square bracket or curly brace, it is parsed as if it were enclosed with `{}` curly braces.
+
+A HOCON file is invalid if it omits the opening `{` but still has a closing `}`; the curly braces must be balanced.
+
+### Key-value separator
+
+The `=` character can be used anywhere JSON allows `:`, i.e. to separate keys from values.
+
+If a key is followed by `{`, the `:` or `=` may be omitted. So `"foo" {}` means `"foo" : {}"`
+
+### Commas
+
+Values in arrays, and fields in objects, need not have a comma between them as long as they have at least one ASCII newline (`\n`, decimal value 10) between them.
+
+The last element in an array or last field in an object may be followed by a single comma. This extra comma is ignored.
+
+ - `[1,2,3,]` and `[1,2,3]` are the same array.
+ - `[1\n2\n3]` and `[1,2,3]` are the same array.
+ - `[1,2,3,,]` is invalid because it has two trailing commas.
+ - `[,1,2,3]` is invalid because it has an initial comma.
+ - `[1,,2,3]` is invalid because it has two commas in a row.
+ - these same comma rules apply to fields in objects.
+
+### Duplicate keys
+
+The JSON spec does not clarify how duplicate keys in the same object should be handled. In HOCON, duplicate keys that appear later override those that appear earlier, unless both values are objects. If both values are objects, then the objects are merged.
+
+Note: this would make HOCON a non-superset of JSON if you assume that JSON requires duplicate keys to have a behavior. The assumption here is that duplicate keys are invalid JSON.
+
+To merge objects:
+
+ - add fields present in only one of the two objects to the merged object.
+ - for non-object-valued fields present in both objects, the field found in the second object must be used.
+ - for object-valued fields present in both objects, the object values should be recursively merged according to these same rules.
+
+Object merge can be prevented by setting the key to another value first. This is because merging is always done two values at a time; if you set a key to an object, a non-object, then an object, first the non-object falls back to the object (non-object always wins), and then the object falls back to the non-object (no merging, object is the new value). So the two objects never see each other.
+
+These two are equivalent:
+
+ {
+ "foo" : { "a" : 42 },
+ "foo" : { "b" : 43 }
+ }
+
+ {
+ "foo" : { "a" : 42, "b" : 43 }
+ }
+
+And these two are equivalent:
+
+ {
+ "foo" : { "a" : 42 },
+ "foo" : null,
+ "foo" : { "b" : 43 }
+ }
+
+ {
+ "foo" : { "b" : 43 }
+ }
+
+The intermediate setting of `"foo"` to `null` prevents the object merge.
+
+### Paths as keys
+
+If a key is a path expression with multiple elements, it is expanded to create an object for each path element other than the last. The last path element, combined with the value, becomes a field in the most-nested object.
+
+In other words:
+
+ foo.bar : 42
+
+is equivalent to:
+
+ foo { bar : 42 }
+
+and:
+
+ foo.bar.baz : 42
+
+is equivalent to:
+
+ foo { bar { baz : 42 } }
+
+and so on. These values are merged in the usual way; which implies that:
+
+ a.x : 42, a.y : 43
+
+is equivalent to:
+
+ a { x : 42, y : 43 }
+
+Because path expressions work like value concatenations, you can have whitespace in keys:
+
+ a b c : 42
+
+is equivalent to:
+
+ "a b c" : 42
+
+Because path expressions are always converted to strings, even single values that would normally have another type become strings.
+
+ - `true : 42` is `"true" : 42`
+ - `3.14 : 42` is `"3.14" : 42`
+
+As a special rule, the unquoted string `include` may not begin a path expression in a key, because it has a special interpretation (see below).
+
+## Substitutions
+
+Substitutions are a way of referring to other parts of the configuration tree.
+
+The syntax is `${pathexpression}` or `${?pathexpression}` where the `pathexpression` is a path expression as described above. This path expression has the same syntax that you could use for an object key.
+
+The `?` in `${?pathexpression}` must not have whitespace before it; the three characters `${?` must be exactly like that, grouped together.
+
+For substitutions which are not found in the configuration tree, implementations may try to resolve them by looking at system environment variables or other external sources of configuration. (More detail on environment variables in a later section.)
+
+Substitutions are not parsed inside quoted strings. To get a string containing a substitution, you must use value concatenation with the substitution in the unquoted portion:
+
+ key : ${animal.favorite} is my favorite animal
+
+Or you could quote the non-substitution portion:
+
+ key : ${animal.favorite}" is my favorite animal"
+
+Substitutions are resolved by looking up the path in the configuration. The path begins with the root configuration object, i.e. it is "absolute" rather than "relative."
+
+Substitution processing is performed as the last parsing step, so a substitution can look forward in the configuration. If a configuration consists of multiple files, it may even end up retrieving a value from another file. If a key has been specified more than once, the substitution will always evaluate to its latest-assigned value (the merged object or the last non-object value that was set).
+
+If a configuration sets a value to `null` then it should not be looked up in the external source. Unfortunately there is no way to "undo" this in a later configuration file; if you have `{ "HOME" : null }` in a root object, then `${HOME}` will never look at the environment variable. There is no equivalent to JavaScript's `delete` operation in other words.
+
+If a substitution does not match any value present in the configuration and is not resolved by an external source, then it is undefined. An undefined substitution with the `${foo}` syntax is invalid and should generate an error.
+
+If a substitution with the `${?foo}` syntax is undefined:
+
+ - if it is the value of an object field then the field should not
+ be created. If the field would have overridden a previously-set
+ value for the same field, then the previous value remains.
+ - if it is an array element then the element should not be added.
+ - if it is part of a value concatenation then it should become an
+ empty string.
+ - `foo : ${?bar}` would avoid creating field `foo` if `bar` is
+ undefined, but `foo : ${?bar} ${?baz}` would be a value
+ concatenation so if `bar` or `baz` are not defined, the result
+ is an empty string.
+
+Substitutions are only allowed in object field values and array elements (value concatenations), they are not allowed in keys or nested inside other substitutions (path expressions).
+
+A substitution is replaced with any value type (number, object, string, array, true, false, null). If the substitution is the only part of a value, then the type is preserved. Otherwise, it is value-concatenated to form a string.
+
+Circular substitutions are invalid and should generate an error.
+
+Implementations must take care, however, to allow objects to refer to paths within themselves. For example, this must work:
+
+ bar : { foo : 42,
+ baz : ${bar.foo}
+ }
+
+Here, if an implementation resolved all substitutions in `bar` as part of resolving the substitution `${bar.foo}`, there would be a cycle. The implementation must only resolve the `foo` field in `bar`, rather than recursing the entire `bar` object.
+
+## Includes
+
+### Include syntax
+
+An _include statement_ consists of the unquoted string `include` and a single quoted string immediately following it. An include statement can appear in place of an object field.
+
+If the unquoted string `include` appears at the start of a path expression where an object key would be expected, then it is not interpreted as a path expression or a key.
+
+Instead, the next value must be a _quoted_ string. The quoted string is interpreted as a filename or resource name to be included.
+
+Together, the unquoted `include` and the quoted string substitute for an object field syntactically, and are separated from the following object fields or includes by the usual comma (and as usual the comma may be omitted if there's a newline).
+
+If an unquoted `include` at the start of a key is followed by anything other than a single quoted string, it is invalid and an error should be generated.
+
+There can be any amount of whitespace, including newlines, between the unquoted `include` and the quoted string.
+
+Value concatenation is NOT performed on the "argument" to `include`. The argument must be a single quoted string. No substitutions are allowed, and the argument may not be an unquoted string or any other kind of value.
+
+Unquoted `include` has no special meaning if it is not the start of a key's path expression.
+
+It may appear later in the key:
+
+ # this is valid
+ { foo include : 42 }
+ # equivalent to
+ { "foo include" : 42 }
+
+It may appear as an object or array value:
+
+ { foo : include } # value is the string "include"
+ [ include ] # array of one string "include"
+
+You can quote `"include"` if you want a key that starts with the word `"include"`, only unquoted `include` is special:
+
+ { "include" : 42 }
+
+### Include semantics: merging
+
+An _including file_ contains the include statement and an _included file_ is the one specified in the include statement. (They need not be regular files on a filesystem, but assume they are for the moment.)
+
+An included file must contain an object, not an array. This is significant because both JSON and HOCON allow arrays as root values in a document.
+
+If an included file contains an array as the root value, it is invalid and an error should be generated.
+
+The included file should be parsed, producing a root object. The keys from the root object are conceptually substituted for the include statement in the including file.
+
+ - If a key in the included object occurred prior to the include
+ statement in the including object, the included key's value
+ overrides or merges with the earlier value, exactly as with
+ duplicate keys found in a single file.
+ - If the including file repeats a key from an earlier-included
+ object, the including file's value would override or merge
+ with the one from the included file.
+
+### Include semantics: substitution
+
+Substitutions in included files are looked up at two different paths; first, relative to the root of the included file; second, relative to the root of the including configuration.
+
+Recall that substitution happens as a final step, _after_ parsing. It should be done for the entire app's configuration, not for single files in isolation.
+
+Therefore, if an included file contains substitutions, they must be "fixed up" to be relative to the app's configuration root.
+
+Say for example that the root configuration is this:
+
+ { a : { include "foo.conf" } }
+
+And "foo.conf" might look like this:
+
+ { x : 10, y : ${x} }
+
+If you parsed "foo.conf" in isolation, then `${x}` would evaluate to 10, the value at the path `x`. If you include "foo.conf" in an object at key `a`, however, then it must be fixed up to be `${a.x}` rather than `${x}`.
+
+Say that the root configuration redefines `a.x`, like this:
+
+ {
+ a : { include "foo.conf" }
+ a : { x : 42 }
+ }
+
+Then the `${x}` in "foo.conf", which has been fixed up to `${a.x}`, would evaluate to `42` rather than to `10`. Substitution happens _after_ parsing the whole configuration.
+
+However, there are plenty of cases where the included file might intend to refer to the application's root config. For example, to get a value from a system property or from the reference configuration. So it's not enough to only look up the "fixed up" path, it's necessary to look up the original path as well.
+
+### Include semantics: missing files
+
+If an included file does not exist, the include statement should be silently ignored (as if the included file contained only an empty object).
+
+### Include semantics: locating resources
+
+Conceptually speaking, the quoted string in an include statement identifies a file or other resource "adjacent to" the one being parsed and of the same type as the one being parsed. The meaning of "adjacent to", and the string itself, has to be specified separately for each kind of resource.
+
+Implementations may vary in the kinds of resources they support including.
+
+On the Java Virtual Machine, if an include statement does not identify anything "adjacent to" the including resource, implementations may wish to fall back to a classpath resource. This allows configurations found in files or URLs to access classpath resources.
+
+For resources located on the Java classpath:
+
+ - included resources are looked up by calling `getResource()` on
+ the same class loader used to look up the including resource.
+ - if the included resource name is absolute (starts with '/')
+ then it should be passed to `getResource()` with the '/'
+ removed.
+ - if the included resource name does not start with '/' then it
+ should have the "directory" of the including resource.
+ prepended to it, before passing it to `getResource()`. If the
+ including resource is not absolute (no '/') and has no "parent
+ directory" (is just a single path element), then the included
+ relative resource name should be left as-is.
+ - it would be wrong to use `getResource()` to get a URL and then
+ locate the included name relative to that URL, because a class
+ loader is not required to have a one-to-one mapping between
+ paths in its URLs and the paths it handles in `getResource()`.
+ In other words, the "adjacent to" computation should be done
+ on the resource name not on the resource's URL.
+
+For plain files on the filesystem:
+
+ - if the included file is an absolute path then it should be kept
+ absolute and loaded as such.
+ - if the included file is a relative path, then it should be
+ located relative to the directory containing the including
+ file. The current working directory of the process parsing a
+ file must NOT be used when interpreting included paths.
+ - if the file is not found, fall back to the classpath resource.
+ The classpath resource should not have any package name added
+ in front, it should be relative to the "root"; which means any
+ leading "/" should just be removed (absolute is the same as
+ relative since it's root-relative). The "/" is handled for
+ consistency with including resources from inside other
+ classpath resources, where the resource name may not be
+ root-relative and "/" allows specifying relative to root.
+
+URLs:
+
+ - for both filesystem files and Java resources, if the
+ included name is a URL (begins with a protocol), it would
+ be reasonable behavior to try to load the URL rather than
+ treating the name as a filename or resource name.
+ - for files loaded from a URL, "adjacent to" should be based
+ on parsing the URL's path component, replacing the last
+ path element with the included name.
+ - file: URLs should behave in exactly the same way as a plain
+ filename
+
+## Duration format
+
+The supported unit strings for duration are case sensitive and must be lowercase. Exactly these strings are supported:
+
+ - `ns`, `nanosecond`, `nanoseconds`
+ - `us`, `microsecond`, `microseconds`
+ - `ms`, `millisecond`, `milliseconds`
+ - `s`, `second`, `seconds`
+ - `m`, `minute`, `minutes`
+ - `h`, `hour`, `hours`
+ - `d`, `day`, `days`
+
+## Size in bytes format
+
+For single bytes, exactly these strings are supported:
+
+ - `B`, `b`, `byte`, `bytes`
+
+For powers of ten, exactly these strings are supported:
+
+ - `kB`, `kilobyte`, `kilobytes`
+ - `MB`, `megabyte`, `megabytes`
+ - `GB`, `gigabyte`, `gigabytes`
+ - `TB`, `terabyte`, `terabytes`
+ - `PB`, `petabyte`, `petabytes`
+ - `EB`, `exabyte`, `exabytes`
+ - `ZB`, `zettabyte`, `zettabytes`
+ - `YB`, `yottabyte`, `yottabytes`
+
+For powers of two, exactly these strings are supported:
+
+ - `K`, `k`, `Ki`, `KiB`, `kibibyte`, `kibibytes`
+ - `M`, `m`, `Mi`, `MiB`, `mebibyte`, `mebibytes`
+ - `G`, `g`, `Gi`, `GiB`, `gibibyte`, `gibibytes`
+ - `T`, `t`, `Ti`, `TiB`, `tebibyte`, `tebibytes`
+ - `P`, `p`, `Pi`, `PiB`, `pebibyte`, `pebibytes`
+ - `E`, `e`, `Ei`, `EiB`, `exbibyte`, `exbibytes`
+ - `Z`, `z`, `Zi`, `ZiB`, `zebibyte`, `zebibytes`
+ - `Y`, `y`, `Yi`, `YiB`, `yobibyte`, `yobibytes`
+
+## Conventional override by system properties
+
+Java system properties override settings found in the `application.conf` and `reference.conf` files. This supports specifying config options on the command line, for example `sbt -Dkey=value run`.
+
+> **Note**: Play forks the JVM for tests - and so to use command line overrides in tests you must add `Keys.fork in Test := false` in `build.sbt` before you can use them for a test.
diff --git a/manual/working/commonGuide/configuration/Configuration.md b/manual/working/commonGuide/configuration/Configuration.md
new file mode 100644
index 00000000..fb37b6f8
--- /dev/null
+++ b/manual/working/commonGuide/configuration/Configuration.md
@@ -0,0 +1,15 @@
+
+# Configuration
+
+This section explains how to configure your Play application.
+
+- [[Configuration file syntax and features|ConfigFile]]
+- [[Configuring the application secret|ApplicationSecret]]
+- [[Configuring the session cookie|SettingsSession]]
+- [[Configuring the JDBC connection pool|SettingsJDBC]]
+- [[Configuring Play's thread pools|ThreadPools]]
+- [[Configuring Akka Http Server Backend|SettingsAkkaHttp]]
+- [[Configuring Netty Server Backend|SettingsNetty]]
+- [[Configuring logging|SettingsLogger]]
+- [[Configuring WS SSL|WsSSL]]
+- [[Configuring WS Cache|WsCache]]
diff --git a/manual/working/commonGuide/configuration/SettingsAkkaHttp.md b/manual/working/commonGuide/configuration/SettingsAkkaHttp.md
new file mode 100644
index 00000000..5706b1f4
--- /dev/null
+++ b/manual/working/commonGuide/configuration/SettingsAkkaHttp.md
@@ -0,0 +1,51 @@
+
+# Configuring the Akka HTTP server backend
+
+By default, Play uses the [[Akka HTTP server backend|AkkaHttpServer]].
+
+Like the rest of Play, the Akka HTTP server backend is configured with Typesafe Config.
+
+@[](/confs/play-akka-http-server/reference.conf)
+
+The configurations above are specific to Akka HTTP server backend, but other more generic configurations are also available:
+
+@[](/confs/play-server/reference.conf)
+
+You can read more about the configuration settings in the [Akka HTTP documentation](https://doc.akka.io/docs/akka-http/current/configuration.html?language=scala).
+
+> **Note:** Akka HTTP has a number of [timeouts configurations](https://doc.akka.io/docs/akka-http/current/common/timeouts.html?language=scala#server-timeouts) that you can use to protect your application from attacks or programming mistakes. The Akka HTTP Server in Play will automatically recognize all these Akka configurations. For example, if you have `idle-timeout` and `request-timeout` configurations like below:
+>
+> ```
+> akka.http.server.idle-timeout = 20s
+> akka.http.server.request-timeout = 30s
+> ```
+>
+> They will be automatically recognized. Keep in mind that Play configurations listed above will override the Akka ones.
+
+There is also a separate configuration file for the HTTP/2 support in Akka HTTP, if you have [[enabled the `AkkaHttp2Support` plugin|AkkaHttpServer#HTTP/2-support-(experimental)]]:
+
+@[](/confs/play-akka-http2-support/reference.conf)
+
+> **Note:** In dev mode, when you use the `run` command, your `application.conf` settings will not be picked up by the server. This is because in dev mode the server starts before the application classpath is available. There are several [[other options|ConfigFile#Using-with-the-run-command]] you'll need to use instead.
+
+## Direct Akka HTTP configuration
+
+If you need direct access to Akka HTTP's `ServerSettings` and `ParserSettings` objects you can do this by extending Play's `AkkaHttpServer` class with your own. The `AkkaHttpServer` class has several protected methods which can be overridden to change how Play configures its Akka HTTP backend.
+
+Note that writing your own server class is advanced usage. Usually you can do all the configuration you need through normal configuration settings.
+
+The code below shows an example of a custom server which modifies some Akka HTTP settings. Below the server class is a `ServerProvider` class which acts as a factory for the custom server.
+
+@[custom-akka-http-server](code/CustomAkkaHttpServer.scala)
+
+Once you've written a custom server and `ServerProvider` class you'll need to tell Play about them by setting the `play.server.provider` configuration option to the full name of your `ServerProvider` class.
+
+For example, adding the following settings to your `build.sbt` and `application.conf` will tell Play to use your new server for both the sbt `run` task and when your application is deployed.
+
+`build.sbt`:
+
+@[custom-akka-http-server-provider](code/build.sbt)
+
+`application.conf`:
+
+@[custom-akka-http-server-provider](code/application.conf)
\ No newline at end of file
diff --git a/manual/working/commonGuide/configuration/SettingsJDBC.md b/manual/working/commonGuide/configuration/SettingsJDBC.md
new file mode 100644
index 00000000..d37602a7
--- /dev/null
+++ b/manual/working/commonGuide/configuration/SettingsJDBC.md
@@ -0,0 +1,39 @@
+
+# Configuring the JDBC pool.
+
+The Play JDBC datasource is managed by [HikariCP](https://brettwooldridge.github.io/HikariCP/).
+
+## Special URLs
+
+Play supports special url format for both **MySQL** and **PostgreSQL**:
+
+```
+# To configure MySQL
+db.default.url="mysql://user:password@localhost/database"
+
+# To configure PostgreSQL
+db.default.url="postgres://user:password@localhost/database"
+```
+
+A non-standard port of the database service can be specified:
+
+```
+# To configure MySQL running in Docker
+db.default.url="mysql://user:password@localhost:port/database"
+
+# To configure PostgreSQL running in Docker
+db.default.url="postgres://user:password@localhost:port/database"
+```
+
+## Reference
+
+In addition to the classical `driver`, `url`, `username`, `password` configuration properties, it also supports additional tuning parameters if you need them. The `play.db.prototype` configuration from the Play JDBC `reference.conf` is used as the prototype for the configuration for all database connections. The defaults for all the available configuration options can be seen here:
+
+@[](/confs/play-jdbc/reference.conf)
+
+When you need to specify some settings for a connection pool, you can override the prototype settings. For example, to set the default connection pool for BoneCP and set maxConnectionsPerPartition for the default pool, you would set the following in your `application.conf` file:
+
+```
+play.db.pool=bonecp
+play.db.prototype.bonecp.maxConnectionsPerPartition = 50
+```
diff --git a/manual/working/commonGuide/configuration/SettingsLogger.md b/manual/working/commonGuide/configuration/SettingsLogger.md
new file mode 100644
index 00000000..9cacdc0d
--- /dev/null
+++ b/manual/working/commonGuide/configuration/SettingsLogger.md
@@ -0,0 +1,240 @@
+
+# Configuring logging
+
+Play uses SLF4J for logging, backed by [Logback](https://logback.qos.ch/) as its default logging engine. See the [Logback documentation](https://logback.qos.ch/manual/configuration.html) for details on configuration.
+
+## Default configuration
+
+In dev mode Play uses the following default configuration:
+
+@[](/confs/play-logback/logback-play-dev.xml)
+
+Play uses the following default configuration in production:
+
+@[](/confs/play-logback/logback-play-default.xml)
+
+A few things to note about these configurations:
+
+* These default configs specify only a console logger which outputs only 10 lines of an exception stack trace.
+* Play uses ANSI color codes by default in level messages.
+* For production, the default config puts the console logger behind the logback [AsyncAppender](https://logback.qos.ch/manual/appenders.html#AsyncAppender). For details on the performance implications on this, see this [blog post](https://blog.takipi.com/how-to-instantly-improve-your-java-logging-with-7-logback-tweaks/).
+* In order to guarantee that logged messages have had a chance to be processed by asynchronous appenders (including the TCP appender) and ensure background threads have been stopped, you'll need to cleanly shut down logback when your application exits. For details on a shutdown hook, see this [documentation](https://logback.qos.ch/manual/configuration.html#shutdownHook). Also [you must specify](https://jira.qos.ch/browse/LOGBACK-1090) DelayingShutdownHook explicitly: `` .
+
+To add a file logger, add the following appender to your `conf/logback.xml` file:
+
+```xml
+
+ ${application.home:-.}/logs/application.log
+
+ %date [%level] from %logger in %thread - %message%n%xException
+
+
+```
+
+Optionally use the async appender to wrap the `FileAppender`:
+```xml
+
+
+
+```
+
+Add the necessary appender(s) to the root:
+```xml
+
+
+
+
+```
+
+## Security Logging
+
+A security marker has been added for security related operations in Play, and failed security checks now log at WARN level, with the security marker set. This ensures that developers always know why a particular request is failing, which is important now that security filters are enabled by default in Play.
+
+The security marker also allows security failures to be triggered or filtered distinct from normal logging. For example, to disable all logging with the SECURITY marker set, add the following lines to the `logback.xml` file:
+
+```xml
+
+ SECURITY
+ DENY
+
+```
+
+In addition, log events using the security marker can also trigger a message to a Security Information & Event Management (SEIM) engine for further processing.
+
+## Using a custom application loader
+
+Note that when using a custom application loader that does not extend the default `GuiceApplicationLoader` (for example when using [[compile-time dependency injection|ScalaCompileTimeDependencyInjection]]), the `LoggerConfigurator` needs to be manually invoked to pick up your custom configuration. You can do this with code like the following:
+
+@[basicextended](../../scalaGuide/main/dependencyinjection/code/CompileTimeDependencyInjection.scala)
+
+## Custom configuration
+
+For any custom configuration, you will need to specify your own Logback configuration file.
+
+### Using a configuration file from project source
+
+You can provide a default logging configuration by providing a file `conf/logback.xml`.
+
+### Using an external configuration file
+
+You can also specify a configuration file via a System property. This is particularly useful for production environments where the configuration file may be managed outside of your application source.
+
+> **Note**: The logging system gives top preference to configuration files specified by system properties, secondly to files in the `conf` directory, and lastly to the default. This allows you to customize your application's logging configuration and still override it for specific environments or developer setups.
+
+#### Using `-Dlogger.resource`
+
+Specify a configuration file to be loaded from the classpath:
+
+```
+$ start -Dlogger.resource=prod-logger.xml
+```
+
+#### Using `-Dlogger.file`
+
+Specify a configuration file to be loaded from the file system:
+
+```
+$ start -Dlogger.file=/opt/prod/logger.xml
+```
+
+> **Note**: To see which file is being used, you can set a system property to debug it: `-Dlogback.debug=true`.
+
+### Examples
+
+Here's an example of configuration that uses a rolling file appender, as well as a separate appender for outputting an access log:
+
+```xml
+
+
+
+ ${application.home:-.}/logs/application.log
+
+
+ ${application.home:-.}/logs/application-log-%d{yyyy-MM-dd}.gz
+
+ 30
+
+
+ %date{yyyy-MM-dd HH:mm:ss ZZZZ} [%level] from %logger in %thread - %message%n%xException
+
+
+
+
+
+
+ SECURITY
+
+ DENY
+ ACCEPT
+
+ ${application.home:-.}/logs/security.log
+
+ %date [%level] [%marker] from %logger in %thread - %message%n%xException
+
+
+
+
+ ${application.home:-.}/logs/access.log
+
+
+ ${application.home:-.}/logs/access-log-%d{yyyy-MM-dd}.gz
+
+ 7
+
+
+ %date{yyyy-MM-dd HH:mm:ss ZZZZ} %message%n
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+This demonstrates a few useful features:
+
+- It uses `RollingFileAppender` which can help manage growing log files. See more [details here](https://logback.qos.ch/manual/appenders.html#SizeAndTimeBasedRollingPolicy).
+- It writes log files to a directory external to the application so they will not affected by upgrades, etc.
+- The `FILE` appender uses an expanded message format that can be parsed by third party log analytics providers such as Sumo Logic.
+- The `access` logger is routed to a separate log file using the `ACCESS_FILE` appender.
+- Any log messages sent with the "SECURITY" marker attached are logged to the `security.log` file using the [EvaluatorFilter](https://logback.qos.ch/manual/filters.html#evalutatorFilter) and the [OnMarkerEvaluator](https://logback.qos.ch/manual/appenders.html#OnMarkerEvaluator).
+- All loggers are set to a threshold of `INFO` which is a common choice for production logging.
+
+> **Note**: the `file` tag is optional and you can omit it if you want to avoid file renaming. See [Logback docs](https://logback.qos.ch/codes.html#renamingError) for more information.
+
+## Including Properties
+
+By default, only the property `application.home` is exported to the logging framework, meaning that files can be referenced relative to the Play application:
+
+```
+ ${application.home:-}/example.log
+```
+
+If you want to reference properties that are defined in the `application.conf` file, you can add `play.logger.includeConfigProperties=true` to your application.conf file. When the application starts, all properties defined in configuration will be available to the logger:
+
+```
+
+
+ context = ${my.property.defined.in.application.conf} %message%n
+
+
+```
+
+## Akka logging configuration
+
+Akka system logging can be done by changing the `akka` logger to INFO.
+
+```xml
+
+
+
+
+```
+
+You may also wish to configure an appender for the Akka loggers that includes useful properties such as thread and actor address. For more information about configuring Akka's logging, including details on Logback and Slf4j integration, see the [Akka documentation](https://doc.akka.io/docs/akka/2.5/logging.html?language=scala).
+
+## Using a Custom Logging Framework
+
+Play uses Logback by default, but it is possible to configure Play to use another logging framework as long as there is an SLF4J adapter for it. To do this, the `PlayLogback` sbt plugin must be disabled using `disablePlugins`:
+
+```scala
+lazy val root = (project in file("."))
+ .enablePlugins(PlayScala)
+ .disablePlugins(PlayLogback)
+```
+
+From there, a custom logging framework can be used. Here, Log4J 2 is used as an example.
+
+```scala
+libraryDependencies ++= Seq(
+ "org.apache.logging.log4j" % "log4j-slf4j-impl" % "2.4.1",
+ "org.apache.logging.log4j" % "log4j-api" % "2.4.1",
+ "org.apache.logging.log4j" % "log4j-core" % "2.4.1"
+)
+```
+
+Once the libraries and the SLF4J adapter are loaded, the `log4j.configurationFile` system property can be set on the command line as usual.
+
+If custom configuration depending on Play's mode is required, you can do additional customization with the `LoggerConfigurator`. To do this, add a `logger-configurator.properties` to the classpath, with
+
+```properties
+play.logger.configurator=Log4J2LoggerConfigurator
+```
+
+And then extend LoggerConfigurator with any customizations:
+
+Java
+: @[log4j2-class](code/JavaLog4JLoggerConfigurator.java)
+
+Scala
+: @[log4j2-class](code/Log4j2LoggerConfigurator.scala)
diff --git a/manual/working/commonGuide/configuration/SettingsNetty.md b/manual/working/commonGuide/configuration/SettingsNetty.md
new file mode 100644
index 00000000..f229e80c
--- /dev/null
+++ b/manual/working/commonGuide/configuration/SettingsNetty.md
@@ -0,0 +1,32 @@
+
+# Configuring Netty Server Backend
+
+The Netty server backend is built on top of [Netty](https://netty.io/).
+
+> **Note**: The Netty server backend is not the default in 2.6.x, and so must be specifically enabled. See more information in [[Netty Server|NettyServer]] documentation.
+
+## Default configuration
+
+Play uses the following default configuration:
+
+@[](/confs/play-netty-server/reference.conf)
+
+The configurations above are specific to Netty server backend, but other more generic configurations are also available:
+
+@[](/confs/play-server/reference.conf)
+
+## Configuring transport socket
+
+Native socket transport has higher performance and produces less garbage but is only available on Linux. You can configure the transport socket type in `application.conf`:
+
+```properties
+play.server {
+ netty {
+ transport = "native"
+ }
+}
+```
+
+## Configuring channel options
+
+The available options are defined in [Netty channel option documentation](https://netty.io/4.1/api/io/netty/channel/ChannelOption.html). If you are using native socket transport you can set [additional options](https://netty.io/4.1/api/io/netty/channel/epoll/EpollChannelOption.html).
diff --git a/manual/working/commonGuide/configuration/SettingsSession.md b/manual/working/commonGuide/configuration/SettingsSession.md
new file mode 100644
index 00000000..192ab143
--- /dev/null
+++ b/manual/working/commonGuide/configuration/SettingsSession.md
@@ -0,0 +1,31 @@
+
+# Configuring the session cookie
+
+Play stores the session using a session cookie in the browser. When you are programming, you will typically access the session through the [[Scala API|ScalaSessionFlash]] or [[Java API|JavaSessionFlash]], but there are useful configuration settings.
+
+Session and flash cookies are stored in [JSON Web Token](https://tools.ietf.org/html/rfc7519) (JWT) format. The encoding is transparent to Play, but there some useful properties of JWT which can be leveraged for session cookies, and can be configured through `application.conf`. Note that JWT is typically used in an HTTP header value, which is not what is active here -- in addition, the JWT is signed using the secret, but is not encrypted by Play.
+
+## Not Before Support
+
+When a session cookie is created, the "issued at" `iat` and "not before" `nbf` claims in JWT will be set to the time of cookie creation, which prevents a cookie from being accepted before the current time.
+
+## Session Timeout / Expiration
+
+By default, there is no technical timeout for the Session. It expires when the user closes the web browser. If you need a functional timeout for a specific application, you set the maximum age of the session cookie by configuring the key `play.http.session.maxAge` in `application.conf`, and this will also set `play.http.session.jwt.expiresAfter` to the same value. The `maxAge` property will remove the cookie from the browser, and the JWT `exp` claim will be set in the cookie, and will make it invalid after the given duration.
+
+## URL Encoded Cookie Encoding
+
+The session cookie uses the JWT cookie encoding. If you want, you can revert back to URL encoded cookie encoding by switching to `play.api.mvc.LegacyCookiesModule` in the application.conf file:
+
+```
+play.modules.disabled+="play.api.mvc.CookiesModule"
+play.modules.enabled+="play.api.mvc.LegacyCookiesModule"
+```
+
+## Session Configuration
+
+The default session configuration is as follows:
+
+@[session-configuration](/confs/play/reference.conf)
+
+
diff --git a/manual/working/commonGuide/configuration/ThreadPools.md b/manual/working/commonGuide/configuration/ThreadPools.md
new file mode 100644
index 00000000..fcdfb3e5
--- /dev/null
+++ b/manual/working/commonGuide/configuration/ThreadPools.md
@@ -0,0 +1,192 @@
+
+# Understanding Play thread pools
+
+Play Framework is, from the bottom up, an asynchronous web framework. Streams are handled asynchronously using iteratees. Thread pools in Play are tuned to use fewer threads than in traditional web frameworks, since IO in play-core never blocks.
+
+Because of this, if you plan to write blocking IO code, or code that could potentially do a lot of CPU intensive work, you need to know exactly which thread pool is bearing that workload, and you need to tune it accordingly. Doing blocking IO without taking this into account is likely to result in very poor performance from Play Framework, for example, you may see only a few requests per second being handled, while CPU usage sits at 5%. In comparison, benchmarks on typical development hardware (eg, a MacBook Pro) have shown Play to be able to handle workloads in the hundreds or even thousands of requests per second without a sweat when tuned correctly.
+
+## Knowing when you are blocking
+
+The most common place where a typical Play application will block is when it's talking to a database. Unfortunately, none of the major databases provide asynchronous database drivers for the JVM, so for most databases, your only option is to using blocking IO. A notable exception to this is [ReactiveMongo](http://reactivemongo.org/), a driver for MongoDB that uses Play's Iteratee library to talk to MongoDB.
+
+Other cases when your code may block include:
+
+* Using REST/WebService APIs through a 3rd party client library (ie, not using Play's asynchronous WS API)
+* Some messaging technologies only provide synchronous APIs to send messages
+* When you open files or sockets directly yourself
+* CPU intensive operations that block by virtue of the fact that they take a long time to execute
+
+In general, if the API you are using returns `Future`s, it is non-blocking, otherwise it is blocking.
+
+> Note that you may be tempted to therefore wrap your blocking code in Futures. This does not make it non-blocking, it just means the blocking will happen in a different thread. You still need to make sure that the thread pool that you are using has enough threads to handle the blocking. Please see Play's example templates on https://playframework.com/download#examples for how to configure your application for a blocking API.
+
+In contrast, the following types of IO do not block:
+
+* The Play WS API
+* Asynchronous database drivers such as ReactiveMongo
+* Sending/receiving messages to/from Akka actors
+
+## Play's thread pools
+
+Play uses a number of different thread pools for different purposes:
+
+* **Internal thread pools** - These are used internally by the server engine for handling IO. An application's code should never be executed by a thread in these thread pools. Play is configured with Akka HTTP server backend by default, and so [[configuration settings|SettingsAkkaHttp]] from `application.conf` should be used to change the backend. Alternately, Play also comes with a Netty server backend which, if enabled, also has settings that can be [[configured|SettingsNetty]] from `application.conf`.
+
+* **Play default thread pool** - This is the thread pool in which all of your application code in Play Framework is executed. It is an Akka dispatcher, and is used by the application `ActorSystem`. It can be configured by configuring Akka, described below.
+
+## Using the default thread pool
+
+All actions in Play Framework use the default thread pool. When doing certain asynchronous operations, for example, calling `map` or `flatMap` on a future, you may need to provide an implicit execution context to execute the given functions in. An execution context is basically another name for a `ThreadPool`.
+
+In most situations, the appropriate execution context to use will be the **Play default thread pool**. This is accessible through `@Inject()(implicit ec: ExecutionContext)` This can be used by injecting it into your Scala source file:
+
+@[global-thread-pool](code/ThreadPools.scala)
+
+or using [`CompletionStage`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html) with an [`HttpExecutionContext`](api/java/play/libs/concurrent/HttpExecutionContext.html) in Java code:
+
+@[http-execution-context](code/detailedtopics/httpec/MyController.java)
+
+This execution context connects directly to the Application's `ActorSystem` and uses the [default dispatcher](https://doc.akka.io/docs/akka/2.5/dispatchers.html?language=scala).
+
+### Configuring the default thread pool
+
+The default thread pool can be configured using standard Akka configuration in `application.conf` under the `akka` namespace. Here is default configuration for Play's thread pool:
+
+@[default-config](code/ThreadPools.scala)
+
+This configuration instructs Akka to create 1 thread per available processor, with a maximum of 24 threads in the pool.
+
+You can also try the default Akka configuration:
+
+@[akka-default-config](code/ThreadPools.scala)
+
+The full configuration options available to you can be found [here](https://doc.akka.io/docs/akka/2.5.3/java/general/configuration.html#listing-of-the-reference-configuration).
+
+## Using other thread pools
+
+In certain circumstances, you may wish to dispatch work to other thread pools. This may include CPU heavy work, or IO work, such as database access. To do this, you should first create a `ThreadPool`, this can be done easily in Scala:
+
+@[my-context-usage](code/ThreadPools.scala)
+
+In this case, we are using Akka to create the `ExecutionContext`, but you could also easily create your own `ExecutionContext`s using Java executors, or the Scala fork join thread pool, for example. Play provides `play.libs.concurrent.CustomExecutionContext` and `play.api.libs.concurrent.CustomExecutionContext` that can be used to create your own execution contexts. Please see [[ScalaAsync]] or [[JavaAsync]] for further details.
+
+To configure this Akka execution context, you can add the following configuration to your `application.conf`:
+
+@[my-context-config](code/ThreadPools.scala)
+
+To use this execution context in Scala, you would simply use the scala `Future` companion object function:
+
+@[my-context-explicit](code/ThreadPools.scala)
+
+or you could just use it implicitly:
+
+@[my-context-implicit](code/ThreadPools.scala)
+
+In addition, please see the example templates on https://playframework.com/download#examples for examples of how to configure your application for a blocking API.
+
+## Class loaders and thread locals
+
+Class loaders and thread locals need special handling in a multithreaded environment such as a Play program.
+
+### Application class loader
+
+In a Play application the [thread context class loader](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#getContextClassLoader--) may not always be able to load application classes. You should explicitly use the application class loader to load classes.
+
+Java
+: @[using-app-classloader](code/detailedtopics/ThreadPoolsJava.java)
+
+Scala
+: @[using-app-classloader](code/ThreadPools.scala)
+
+Being explicit about loading classes is most important when running Play in development mode (using `run`) rather than production mode. That's because Play's development mode uses multiple class loaders so that it can support automatic application reloading. Some of Play's threads might be bound to a class loader that only knows about a subset of your application's classes.
+
+In some cases you may not be able to explicitly use the application classloader. This is sometimes the case when using third party libraries. In this case you may need to set the [thread context class loader](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#getContextClassLoader--) explicitly before you call the third party code. If you do, remember to restore the context class loader back to its previous value once you've finished calling the third party code.
+
+### Java thread locals
+
+Java code in Play uses a `ThreadLocal` to find out about contextual information such as the current HTTP request. Scala code doesn't need to use `ThreadLocal`s because it can use implicit parameters to pass context instead. `ThreadLocal`s are used in Java so that Java code can access contextual information without needing to pass context parameters everywhere.
+
+The problem with using thread locals however is that as soon as control switches to another thread, you lose thread local information. So if you were to map a `CompletionStage` using `thenApplyAsync`, or using `thenApply` at a point in time after the `Future` associated with that `CompletionStage` had completed, and you then try to access the HTTP context (eg, the session or request), it won't work . To address this, Play provides an [`HttpExecutionContext`](api/java/play/libs/concurrent/HttpExecutionContext.html). This allows you to capture the current context in an `Executor`, which you can then pass to the `CompletionStage` `*Async` methods such as `thenApplyAsync()`, and when the executor executes your callback, it will ensure the thread local context is setup so that you can access the request/session/flash/response objects.
+
+To use the `HttpExecutionContext`, inject it into your component, and then pass the current context anytime a `CompletionStage` is interacted with. For example:
+
+@[http-execution-context](code/detailedtopics/httpec/MyController.java)
+
+If you have a custom executor, you can wrap it in an `HttpExecutionContext` simply by passing it to the `HttpExecutionContext`s constructor.
+
+## Best practices
+
+How you should best divide work in your application between different thread pools greatly depends on the types of work that your application is doing, and the control you want to have over how much of which work can be done in parallel. There is no one size fits all solution to the problem, and the best decision for you will come from understanding the blocking-IO requirements of your application and the implications they have on your thread pools. It may help to do load testing on your application to tune and verify your configuration.
+
+> **Note:** In a blocking environment, `thread-pool-executor` is better than `fork-join` because no work-stealing is possible, and a `fixed-pool-size` size should be used and set to the maximum size of the underlying resource.
+>
+> Given the fact that JDBC is blocking, thread pools can be sized to the number of connections available to a database pool, assuming that the thread pool is used exclusively for database access. Fewer threads will not consume the number of connections available. Any more threads than the number of connections available could be wasteful given contention for the connections.
+
+Below we outline a few common profiles that people may want to use in Play Framework:
+
+### Pure asynchronous
+
+In this case, you are doing no blocking IO in your application. Since you are never blocking, the default configuration of one thread per processor suits your use case perfectly, so no extra configuration needs to be done. The Play default execution context can be used in all cases.
+
+### Highly synchronous
+
+This profile matches that of a traditional synchronous IO based web framework, such as a Java servlet container. It uses large thread pools to handle blocking IO. It is useful for applications where most actions are doing database synchronous IO calls, such as accessing a database, and you don't want or need control over concurrency for different types of work. This profile is the simplest for handling blocking IO.
+
+In this profile, you would use the default execution context everywhere, but configure it to have a very large number of threads in its pool. Because the default thread pool is used for both servicing Play requests and database requests, the fixed pool size should be the maximum size of database connection pool, plus the number of cores, plus a couple extra for housekeeping, like so:
+
+@[highly-synchronous](code/ThreadPools.scala)
+
+This profile is recommended for Java applications that do synchronous IO, since it is harder in Java to dispatch work to other threads.
+
+In addition, please see the example templates on https://playframework.com/download#examples for examples of how to configure your application for a blocking API.
+
+### Many specific thread pools
+
+This profile is for when you want to do a lot of synchronous IO, but you also want to control exactly how much of which types of operations your application does at once. In this profile, you would only do non blocking operations in the default execution context, and then dispatch blocking operations to different execution contexts for those specific operations.
+
+In this case, you might create a number of different execution contexts for different types of operations, like this:
+
+@[many-specific-contexts](code/ThreadPools.scala)
+
+These might then be configured like so:
+
+@[many-specific-config](code/ThreadPools.scala)
+
+Then in your code, you would create `Future`s and pass the relevant `ExecutionContext` for the type of work that `Future` was doing.
+
+> **Note:** The configuration namespace can be chosen freely, as long as it matches the dispatcher ID passed to `app.actorSystem.dispatchers.lookup`. The `CustomExecutionContext` class will do this for you automatically.
+
+### Few specific thread pools
+
+This is a combination between the many specific thread pools and the highly synchronized profile. You would do most simple IO in the default execution context and set the number of threads there to be reasonably high (say 100), but then dispatch certain expensive operations to specific contexts, where you can limit the number of them that are done at one time.
+
+## Debugging Thread Pools
+
+There are many possible settings for a dispatcher, and it can be hard to see which ones have been applied and what the defaults are, particularly when overriding the default dispatcher. The `akka.log-config-on-start` configuration option shows the entire applied configuration when the application is loaded:
+
+
+```
+akka.log-config-on-start = on
+```
+
+Note that you must have Akka logging set to a debug level to see output, so you should add the following to `logback.xml`:
+
+```
+
+```
+
+Once you see the logged HOCON output, you can copy and paste it into an "example.conf" file and view it in IntelliJ IDEA, which supports HOCON syntax. You should see your changes merged in with Akka's dispatcher, so if you override `thread-pool-executor` you will see it merged:
+
+```
+{
+ # Elided HOCON...
+ "actor" : {
+ "default-dispatcher" : {
+ # application.conf @ file:/Users/wsargent/work/catapi/target/universal/stage/conf/application.conf: 19
+ "executor" : "thread-pool-executor"
+ }
+ }
+}
+```
+
+Note also that Play has different configuration settings for development mode than it does for production. To ensure that the thread pool settings are correct, you should run Play in a [[production configuration|Deploying#Running-a-test-instance]].
diff --git a/manual/working/commonGuide/configuration/WsCache.md b/manual/working/commonGuide/configuration/WsCache.md
new file mode 100644
index 00000000..06664d66
--- /dev/null
+++ b/manual/working/commonGuide/configuration/WsCache.md
@@ -0,0 +1,89 @@
+
+# Configuring WS Cache
+
+[[Play WS|ScalaWS]] allows you to set up HTTP caching from configuration.
+
+## Enabling Cache
+
+You must have a [JSR 107](https://www.jcp.org/en/jsr/detail?id=107) cache implementation (aka JCache) available in your Play application to use Play WS's cache facility. Play comes with an implementation that uses ehcache, so the easiest implementation is to add the following to `build.sbt`:
+
+@[play-ws-cache-deps](code/build.sbt)
+
+And enable the HTTP cache by adding the following to `application.conf`
+
+```
+play.ws.cache.enabled=true
+```
+
+If no JCache implementation is found, then Play WS will use an HTTP Cache with a stub cache that does not store anything.
+
+## Enabling Freshness Heuristics
+
+By default, Play WS does not cache HTTP responses when no explicit cache information is passed in. However, HTTP caching does have an option to cache pages based off heuristics so that you can cache responses even without co-operation from the remote server.
+
+To enable heuristics, set the following in `application.conf`:
+
+```
+play.ws.cache.heuristics.enabled=true
+```
+
+Play WS uses the [LM-Factor algorithm]( https://publicobject.com/2015/03/26/how-do-http-caching-heuristics-work/) to cache HTTP responses.
+
+## Limiting Cache Size
+
+Cache size is limited by the underlying cache implementation. Play WS will create a generic cache if no cache was found, but you should bound the cache explicitly, as JCache does not provide many options.
+
+> **NOTE**: If you do not limit the HTTP cache or expire elements in the cache, then you may cause the JVM to run out of memory.
+
+In ehcache, you can specify an existing cache by specifying [CacheManager](https://static.javadoc.io/javax.cache/cache-api/1.0.0/javax/cache/CacheManager.html) resource explicitly, which is used in `cachingProvider.getCacheManager(uri, environment.classLoader)`:
+
+```
+play.ws.cache.cacheManagerResource="ehcache-play-ws-cache.xml"
+```
+
+and then adding a cache such as following into the `conf` directory:
+
+```xml
+
+
+
+
+
+```
+
+> **NOTE**: `play.ws.cache.cacheManagerURI` is deprecated, use `play.ws.cache.cacheManagerResource` with a path on the classpath instead.
+
+## Debugging the Cache
+
+To see exactly what the HTTP caching layer in Play WS is doing, please add the following to `logback.xml`:
+
+```
+
+```
+
+## Defining a Caching Provider
+
+You can define a specific [CachingProvider](https://static.javadoc.io/javax.cache/cache-api/1.0.0/javax/cache/spi/CachingProvider.html) for the WS cache, even if you are already using `ehcache` as a caching provider for Play Cache. For example, you can load the [Caffeine](https://github.com/ben-manes/caffeine/wiki) library:
+
+```
+// https://mvnrepository.com/artifact/com.github.ben-manes.caffeine/jcache
+libraryDependencies += "com.github.ben-manes.caffeine" % "jcache" % "2.4.0"
+```
+
+and then specify [Caffeine JCache](https://github.com/ben-manes/caffeine/wiki/JCache) as the caching provider:
+
+```
+play.ws.cache.cachingProviderName=""
+```
+
+## Reference Configuration
+
+The reference configuration shows the default settings for Play WS Caching:
+
+@[](/confs/play-ahc-ws/reference.conf)
diff --git a/manual/working/commonGuide/configuration/WsSSL.md b/manual/working/commonGuide/configuration/WsSSL.md
new file mode 100644
index 00000000..0c2c3772
--- /dev/null
+++ b/manual/working/commonGuide/configuration/WsSSL.md
@@ -0,0 +1,44 @@
+
+# Configuring WS SSL
+
+[[Play WS|ScalaWS]] allows you to set up HTTPS completely from a configuration file, without the need to write code. It does this by layering the Java Secure Socket Extension (JSSE) with a configuration layer and with reasonable defaults.
+
+JDK 1.8 contains an implementation of JSSE which is [significantly more advanced](https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8.html) than previous versions, and should be used if security is a priority.
+
+> **NOTE**: It is highly recommended (if not required) to use WS SSL with the
+unlimited strength java cryptography extension. You can download the policy files from Oracle's website at [Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download](https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html).
+
+## Table of Contents
+
+The Play WS configuration is based on [Typesafe SSLConfig](https://lightbend.github.io/ssl-config).
+
+For convenience, a table of contents to SSLConfig is provided:
+
+- [Quick Start to WS SSL](https://lightbend.github.io/ssl-config/WSQuickStart.html)
+- [Generating X.509 Certificates](https://lightbend.github.io/ssl-config/CertificateGeneration.html)
+- [Configuring Trust Stores and Key Stores](https://lightbend.github.io/ssl-config/KeyStores.html)
+- [Configuring Protocols](https://lightbend.github.io/ssl-config/Protocols.html)
+- [Configuring Cipher Suites](https://lightbend.github.io/ssl-config/CipherSuites.html)
+- [Configuring Certificate Validation](https://lightbend.github.io/ssl-config/CertificateValidation.html)
+- [Configuring Certificate Revocation](https://lightbend.github.io/ssl-config/CertificateRevocation.html)
+- [Configuring Hostname Verification](https://lightbend.github.io/ssl-config/HostnameVerification.html)
+- [Example Configurations](https://lightbend.github.io/ssl-config/ExampleSSLConfig.html)
+- [Using the Default SSLContext](https://lightbend.github.io/ssl-config/DefaultContext.html)
+- [Debugging SSL Connections](https://lightbend.github.io/ssl-config/DebuggingSSL.html)
+- [Loose Options](https://lightbend.github.io/ssl-config/LooseSSL.html)
+- [Testing SSL](https://lightbend.github.io/ssl-config/TestingSSL.html)
+
+> **NOTE**: The links below are relative to `Typesafe SSLConfig`, which uses the `ssl-config` as a prefix for ssl properties.
+> Play uses the `play.ws.ssl` prefix, so that, for instance the `ssl-config.loose.acceptAnyCertificate` becomes `play.ws.ssl.loose.acceptAnyCertificate` for your play `WSClient` configuration.
+
+## Further Reading
+
+JSSE is a complex product. For convenience, the JSSE materials are provided here:
+
+JDK 1.8:
+
+* [JSSE Reference Guide](https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html)
+* [JSSE Crypto Spec](https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#SSLTLS)
+* [SunJSSE Providers](https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider)
+* [PKI Programmer's Guide](https://docs.oracle.com/javase/8/docs/technotes/guides/security/certpath/CertPathProgGuide.html)
+* [keytool](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html)
diff --git a/manual/working/commonGuide/configuration/code/Configuration.scala b/manual/working/commonGuide/configuration/code/Configuration.scala
new file mode 100644
index 00000000..86ce74a7
--- /dev/null
+++ b/manual/working/commonGuide/configuration/code/Configuration.scala
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+// With Play Scala
+
+object DependencyInjection {
+ //#dependency-injection
+ import javax.inject._
+ import play.api.Configuration
+
+ class MyController @Inject()(config: Configuration) {
+ // ...
+ }
+ //#dependency-injection
+}
diff --git a/manual/working/commonGuide/configuration/code/CustomAkkaHttpServer.scala b/manual/working/commonGuide/configuration/code/CustomAkkaHttpServer.scala
new file mode 100644
index 00000000..e23aa195
--- /dev/null
+++ b/manual/working/commonGuide/configuration/code/CustomAkkaHttpServer.scala
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+//#custom-akka-http-server
+//###replace: package server
+package detailedtopics.configuration.customakkaserver
+
+import java.util.Random
+import play.core.server.AkkaHttpServer
+import play.core.server.AkkaHttpServerProvider
+import play.core.server.ServerProvider
+import akka.http.scaladsl.ConnectionContext
+import akka.http.scaladsl.model.HttpMethod
+import akka.http.scaladsl.settings.ParserSettings
+import akka.http.scaladsl.settings.ServerSettings
+
+/** A custom Akka HTTP server with advanced configuration. */
+class CustomAkkaHttpServer(context: AkkaHttpServer.Context) extends AkkaHttpServer(context) {
+ protected override def createParserSettings(): ParserSettings = {
+ val defaultSettings: ParserSettings =
+ super.createParserSettings()
+ defaultSettings.withCustomMethods(HttpMethod.custom("TICKLE"))
+ }
+ protected override def createServerSettings(
+ port: Int,
+ connectionContext: ConnectionContext,
+ secure: Boolean
+ ): ServerSettings = {
+ val defaultSettings: ServerSettings =
+ super.createServerSettings(port, connectionContext, secure)
+ defaultSettings.withWebsocketRandomFactory(() => new Random())
+ }
+}
+
+/** A factory that instantiates a CustomAkkaHttpServer. */
+class CustomAkkaHttpServerProvider extends ServerProvider {
+ def createServer(context: ServerProvider.Context) = {
+ val serverContext = AkkaHttpServer.Context.fromServerProviderContext(context)
+ new CustomAkkaHttpServer(serverContext)
+ }
+}
+//#custom-akka-http-server
diff --git a/manual/working/commonGuide/configuration/code/JavaLog4JLoggerConfigurator.java b/manual/working/commonGuide/configuration/code/JavaLog4JLoggerConfigurator.java
new file mode 100644
index 00000000..7d734b45
--- /dev/null
+++ b/manual/working/commonGuide/configuration/code/JavaLog4JLoggerConfigurator.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+// #log4j2-class
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigFactory;
+import org.slf4j.ILoggerFactory;
+import play.Environment;
+import play.LoggerConfigurator;
+import play.Mode;
+import play.api.PlayException;
+
+import java.io.File;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+// ###skip: 1
+/*
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.*;
+import org.apache.logging.log4j.core.config.Configurator;
+//###skip: 1
+*/
+
+public class JavaLog4JLoggerConfigurator implements LoggerConfigurator {
+
+ private ILoggerFactory factory;
+
+ @Override
+ public void init(File rootPath, Mode mode) {
+ Map properties = new HashMap<>();
+ properties.put("application.home", rootPath.getAbsolutePath());
+
+ String resourceName = "log4j2.xml";
+ URL resourceUrl = this.getClass().getClassLoader().getResource(resourceName);
+ configure(properties, Optional.ofNullable(resourceUrl));
+ }
+
+ @Override
+ public void configure(Environment env) {
+ Map properties =
+ LoggerConfigurator.generateProperties(env, ConfigFactory.empty(), Collections.emptyMap());
+ URL resourceUrl = env.resource("log4j2.xml");
+ configure(properties, Optional.ofNullable(resourceUrl));
+ }
+
+ @Override
+ public void configure(
+ Environment env, Config configuration, Map optionalProperties) {
+ // LoggerConfigurator.generateProperties enables play.logger.includeConfigProperties=true
+ Map properties =
+ LoggerConfigurator.generateProperties(env, configuration, optionalProperties);
+ URL resourceUrl = env.resource("log4j2.xml");
+ configure(properties, Optional.ofNullable(resourceUrl));
+ }
+
+ @Override
+ public void configure(Map properties, Optional config) {
+ try {
+ LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
+ loggerContext.setConfigLocation(config.get().toURI());
+
+ factory = org.slf4j.impl.StaticLoggerBinder.getSingleton().getLoggerFactory();
+ } catch (URISyntaxException ex) {
+ throw new PlayException(
+ "log4j2.xml resource was not found",
+ "Could not parse the location for log4j2.xml resource",
+ ex);
+ }
+ }
+
+ @Override
+ public ILoggerFactory loggerFactory() {
+ return factory;
+ }
+
+ @Override
+ public void shutdown() {
+ LoggerContext loggerContext = (LoggerContext) LogManager.getContext();
+ Configurator.shutdown(loggerContext);
+ }
+}
+// #log4j2-class
diff --git a/manual/working/commonGuide/configuration/code/Log4j2LoggerConfigurator.scala b/manual/working/commonGuide/configuration/code/Log4j2LoggerConfigurator.scala
new file mode 100644
index 00000000..5cd83189
--- /dev/null
+++ b/manual/working/commonGuide/configuration/code/Log4j2LoggerConfigurator.scala
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+//#log4j2-class
+import java.io.File
+import java.net.URI
+import java.net.URL
+
+//###skip: 1
+/*
+import play.api.{Mode, Configuration, Environment, LoggerConfigurator}
+
+import org.slf4j.ILoggerFactory
+
+import org.apache.logging.log4j.LogManager
+import org.apache.logging.log4j.core._
+import org.apache.logging.log4j.core.config.Configurator
+//###skip: 1
+ */
+
+import play.api.Mode
+import play.api.Configuration
+import play.api.Environment
+import play.api.LoggerConfigurator
+import org.slf4j.ILoggerFactory
+
+class Log4J2LoggerConfigurator extends LoggerConfigurator {
+
+ private var factory: ILoggerFactory = _
+
+ override def init(rootPath: File, mode: Mode): Unit = {
+ val properties = Map("application.home" -> rootPath.getAbsolutePath)
+ val resourceName = "log4j2.xml"
+ val resourceUrl = Option(this.getClass.getClassLoader.getResource(resourceName))
+ configure(properties, resourceUrl)
+ }
+
+ override def shutdown(): Unit = {
+ val context = LogManager.getContext().asInstanceOf[LoggerContext]
+ Configurator.shutdown(context)
+ }
+
+ override def configure(env: Environment): Unit = {
+ val properties = LoggerConfigurator.generateProperties(env, Configuration.empty, Map.empty)
+ val resourceUrl = env.resource("log4j2.xml")
+ configure(properties, resourceUrl)
+ }
+
+ override def configure(
+ env: Environment,
+ configuration: Configuration,
+ optionalProperties: Map[String, String]
+ ): Unit = {
+ // LoggerConfigurator.generateProperties enables play.logger.includeConfigProperties=true
+ val properties = LoggerConfigurator.generateProperties(env, configuration, optionalProperties)
+ val resourceUrl = env.resource("log4j2.xml")
+ configure(properties, resourceUrl)
+ }
+
+ override def configure(properties: Map[String, String], config: Option[URL]): Unit = {
+ val context = LogManager.getContext(false).asInstanceOf[LoggerContext]
+ context.setConfigLocation(config.get.toURI)
+
+ factory = org.slf4j.impl.StaticLoggerBinder.getSingleton.getLoggerFactory
+ }
+
+ override def loggerFactory: ILoggerFactory = factory
+}
+//#log4j2-class
+
+object Configurator {
+ def shutdown(context: Any): Unit = ???
+
+}
+
+object LogManager {
+ def getContext(): LoggerContext = ???
+
+ def getContext(b: Boolean): LoggerContext = ???
+
+}
+
+class LoggerContext {
+ def setConfigLocation(toURI: URI): Unit = ???
+
+}
diff --git a/manual/working/commonGuide/configuration/code/ThreadPools.scala b/manual/working/commonGuide/configuration/code/ThreadPools.scala
new file mode 100644
index 00000000..224297eb
--- /dev/null
+++ b/manual/working/commonGuide/configuration/code/ThreadPools.scala
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package detailedtopics.configuration.threadpools
+
+import javax.inject.Inject
+
+import play.api.mvc._
+import play.api.test._
+import play.api._
+import com.typesafe.config.ConfigFactory
+import akka.actor.ActorSystem
+
+import scala.concurrent.ExecutionContext
+import scala.concurrent.Future
+import scala.concurrent.TimeoutException
+
+import org.specs2.execute.AsResult
+
+class ThreadPoolsSpec extends PlaySpecification {
+
+ "Play's thread pools" should {
+
+ "make a global thread pool available" in new WithApplication() {
+ val controller = app.injector.instanceOf[Samples]
+ contentAsString(controller.someAsyncAction(FakeRequest())) must startWith("The answer is 42")
+ }
+
+ "have a global configuration" in {
+ val config = """#default-config
+ akka {
+ actor {
+ default-dispatcher {
+ fork-join-executor {
+ # Settings this to 1 instead of 3 seems to improve performance.
+ parallelism-factor = 1.0
+
+ # @richdougherty: Not sure why this is set below the Akka
+ # default.
+ parallelism-max = 24
+
+ # Setting this to LIFO changes the fork-join-executor
+ # to use a stack discipline for task scheduling. This usually
+ # improves throughput at the cost of possibly increasing
+ # latency and risking task starvation (which should be rare).
+ task-peeking-mode = LIFO
+ }
+ }
+ }
+ }
+ #default-config """
+ val parsed = ConfigFactory.parseString(config)
+ val actorSystem = ActorSystem("test", parsed.getConfig("akka"))
+ actorSystem.terminate()
+ success
+ }
+
+ "use akka default thread pool configuration" in {
+ val config = """#akka-default-config
+ akka {
+ actor {
+ default-dispatcher {
+ # This will be used if you have set "executor = "fork-join-executor""
+ fork-join-executor {
+ # Min number of threads to cap factor-based parallelism number to
+ parallelism-min = 8
+
+ # The parallelism factor is used to determine thread pool size using the
+ # following formula: ceil(available processors * factor). Resulting size
+ # is then bounded by the parallelism-min and parallelism-max values.
+ parallelism-factor = 3.0
+
+ # Max number of threads to cap factor-based parallelism number to
+ parallelism-max = 64
+
+ # Setting to "FIFO" to use queue like peeking mode which "poll" or "LIFO" to use stack
+ # like peeking mode which "pop".
+ task-peeking-mode = "FIFO"
+ }
+ }
+ }
+ }
+ #akka-default-config """
+ val parsed = ConfigFactory.parseString(config)
+ val actorSystem = ActorSystem("test", parsed.getConfig("akka"))
+ actorSystem.terminate()
+ success
+ }
+
+ "allow configuring a custom thread pool" in runningWithConfig(
+ """#my-context-config
+ my-context {
+ fork-join-executor {
+ parallelism-factor = 20.0
+ parallelism-max = 200
+ }
+ }
+ #my-context-config """
+ ) { implicit app =>
+ val akkaSystem = app.actorSystem
+ //#my-context-usage
+ val myExecutionContext: ExecutionContext = akkaSystem.dispatchers.lookup("my-context")
+ //#my-context-usage
+ await(Future(Thread.currentThread().getName)(myExecutionContext)) must startWith("application-my-context")
+
+ //#my-context-explicit
+ Future {
+ // Some blocking or expensive code here
+ }(myExecutionContext)
+ //#my-context-explicit
+
+ {
+ //#my-context-implicit
+ implicit val ec = myExecutionContext
+
+ Future {
+ // Some blocking or expensive code here
+ }
+ //#my-context-implicit
+ }
+ success
+ }
+
+ "allow access to the application classloader" in new WithApplication() {
+ val myClassName = "java.lang.String"
+ //#using-app-classloader
+ val myClass = app.classloader.loadClass(myClassName)
+ //#using-app-classloader
+ }
+
+ "allow a synchronous thread pool" in {
+ val config =
+ ConfigFactory.parseString("""#highly-synchronous
+ akka {
+ actor {
+ default-dispatcher {
+ executor = "thread-pool-executor"
+ throughput = 1
+ thread-pool-executor {
+ fixed-pool-size = 55 # db conn pool (50) + number of cores (4) + housekeeping (1)
+ }
+ }
+ }
+ }
+ #highly-synchronous """)
+
+ val actorSystem = ActorSystem("test", config.getConfig("akka"))
+ actorSystem.terminate()
+ success
+ }
+
+ "allow configuring many custom thread pools" in runningWithConfig(
+ """ #many-specific-config
+ contexts {
+ simple-db-lookups {
+ executor = "thread-pool-executor"
+ throughput = 1
+ thread-pool-executor {
+ fixed-pool-size = 20
+ }
+ }
+ expensive-db-lookups {
+ executor = "thread-pool-executor"
+ throughput = 1
+ thread-pool-executor {
+ fixed-pool-size = 20
+ }
+ }
+ db-write-operations {
+ executor = "thread-pool-executor"
+ throughput = 1
+ thread-pool-executor {
+ fixed-pool-size = 10
+ }
+ }
+ expensive-cpu-operations {
+ fork-join-executor {
+ parallelism-max = 2
+ }
+ }
+ }
+ #many-specific-config """
+ ) { implicit app =>
+ val akkaSystem = app.actorSystem
+ //#many-specific-contexts
+ object Contexts {
+ implicit val simpleDbLookups: ExecutionContext = akkaSystem.dispatchers.lookup("contexts.simple-db-lookups")
+ implicit val expensiveDbLookups: ExecutionContext =
+ akkaSystem.dispatchers.lookup("contexts.expensive-db-lookups")
+ implicit val dbWriteOperations: ExecutionContext = akkaSystem.dispatchers.lookup("contexts.db-write-operations")
+ implicit val expensiveCpuOperations: ExecutionContext =
+ akkaSystem.dispatchers.lookup("contexts.expensive-cpu-operations")
+ }
+ //#many-specific-contexts
+ def test(context: ExecutionContext, name: String) = {
+ await(Future(Thread.currentThread().getName)(context)) must startWith("application-contexts." + name)
+ }
+ test(Contexts.simpleDbLookups, "simple-db-lookups")
+ test(Contexts.expensiveDbLookups, "expensive-db-lookups")
+ test(Contexts.dbWriteOperations, "db-write-operations")
+ test(Contexts.expensiveCpuOperations, "expensive-cpu-operations")
+ }
+
+ }
+
+ def runningWithConfig[T: AsResult](config: String)(block: Application => T) = {
+ val parsed: java.util.Map[String, Object] = ConfigFactory.parseString(config).root.unwrapped
+ running(_.configure(Configuration(ConfigFactory.parseString(config))))(block)
+ }
+}
+
+// since specs provides defaultContext, implicitly importing it doesn't work
+//#global-thread-pool
+class Samples @Inject()(components: ControllerComponents)(implicit ec: ExecutionContext)
+ extends AbstractController(components) {
+ def someAsyncAction = Action.async {
+ someCalculation()
+ .map { result =>
+ Ok(s"The answer is $result")
+ }
+ .recover {
+ case e: TimeoutException =>
+ InternalServerError("Calculation timed out!")
+ }
+ }
+
+ def someCalculation(): Future[Int] = {
+ Future.successful(42)
+ }
+}
+//#global-thread-pool
diff --git a/manual/working/commonGuide/configuration/code/application.conf b/manual/working/commonGuide/configuration/code/application.conf
new file mode 100644
index 00000000..2439072b
--- /dev/null
+++ b/manual/working/commonGuide/configuration/code/application.conf
@@ -0,0 +1,4 @@
+//#custom-akka-http-server-provider
+//###replace: play.server.provider = server.CustomAkkaHttpServerProvider
+#play.server.provider = server.CustomAkkaHttpServerProvider
+//#custom-akka-http-server-provider
diff --git a/manual/working/commonGuide/configuration/code/build.sbt b/manual/working/commonGuide/configuration/code/build.sbt
new file mode 100644
index 00000000..44afbec5
--- /dev/null
+++ b/manual/working/commonGuide/configuration/code/build.sbt
@@ -0,0 +1,12 @@
+//#play-ws-cache-deps
+libraryDependencies += ws
+libraryDependencies += ehcache
+//#play-ws-cache-deps
+
+//#prefix-with-play-akka-dev-mode
+PlayKeys.devSettings += "play.akka.dev-mode.akka.cluster.log-info" -> "off"
+//#prefix-with-play-akka-dev-mode
+
+//#custom-akka-http-server-provider
+PlayKeys.devSettings += "play.server.provider" -> "server.CustomAkkaHttpServerProvider"
+//#custom-akka-http-server-provider
diff --git a/manual/working/commonGuide/configuration/code/detailedtopics/ThreadPoolsJava.java b/manual/working/commonGuide/configuration/code/detailedtopics/ThreadPoolsJava.java
new file mode 100644
index 00000000..affad01d
--- /dev/null
+++ b/manual/working/commonGuide/configuration/code/detailedtopics/ThreadPoolsJava.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package detailedtopics;
+
+import org.junit.Test;
+import play.Application;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+import static play.test.Helpers.*;
+
+public class ThreadPoolsJava {
+
+ @Test
+ public void usingAppClassLoader() throws Exception {
+ final Application app = fakeApplication();
+ running(
+ app,
+ () -> {
+ String myClassName = "java.lang.String";
+ try {
+ // #using-app-classloader
+ Class myClass = app.classloader().loadClass(myClassName);
+ // #using-app-classloader
+ assertThat(myClass, notNullValue());
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+}
diff --git a/manual/working/commonGuide/configuration/code/detailedtopics/httpec/MyController.java b/manual/working/commonGuide/configuration/code/detailedtopics/httpec/MyController.java
new file mode 100644
index 00000000..457d7dd6
--- /dev/null
+++ b/manual/working/commonGuide/configuration/code/detailedtopics/httpec/MyController.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package detailedtopics.httpec;
+
+// #http-execution-context
+import play.libs.concurrent.HttpExecutionContext;
+import play.mvc.*;
+
+import javax.inject.Inject;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+
+public class MyController extends Controller {
+
+ private HttpExecutionContext httpExecutionContext;
+
+ @Inject
+ public MyController(HttpExecutionContext ec) {
+ this.httpExecutionContext = ec;
+ }
+
+ public CompletionStage index() {
+ // Use a different task with explicit EC
+ return calculateResponse()
+ .thenApplyAsync(
+ answer -> {
+ // uses Http.Context
+ ctx().flash().put("info", "Response updated!");
+ return ok("answer was " + answer);
+ },
+ httpExecutionContext.current());
+ }
+
+ private static CompletionStage calculateResponse() {
+ return CompletableFuture.completedFuture("42");
+ }
+}
+// #http-execution-context
diff --git a/manual/working/commonGuide/configuration/code/javaguide/configuration/MyController.java b/manual/working/commonGuide/configuration/code/javaguide/configuration/MyController.java
new file mode 100644
index 00000000..48b532e9
--- /dev/null
+++ b/manual/working/commonGuide/configuration/code/javaguide/configuration/MyController.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+// #dependency-injection
+// ###replace: package controllers
+package javaguide.configuration;
+
+import com.typesafe.config.Config;
+import play.mvc.Controller;
+
+import javax.inject.Inject;
+
+public class MyController extends Controller {
+
+ private final Config config;
+
+ @Inject
+ public MyController(Config config) {
+ this.config = config;
+ }
+}
+// #dependency-injection
diff --git a/manual/working/commonGuide/configuration/index.toc b/manual/working/commonGuide/configuration/index.toc
new file mode 100644
index 00000000..79ea380e
--- /dev/null
+++ b/manual/working/commonGuide/configuration/index.toc
@@ -0,0 +1,11 @@
+Configuration:Configuration
+ConfigFile:Configuration file syntax and features
+ApplicationSecret:Configuring the application secret
+SettingsSession:Configuring the session cookie
+SettingsJDBC:Configuring the JDBC connection pool
+ThreadPools:Configuring Play's thread pools
+SettingsAkkaHttp:Configuring Akka Http Server Backend
+SettingsNetty:Configuring Netty Server Backend
+SettingsLogger:Configuring logging
+WsSSL:Configuring WS SSL
+WsCache:Configuring WS Cache
\ No newline at end of file
diff --git a/manual/working/commonGuide/database/Databases.md b/manual/working/commonGuide/database/Databases.md
new file mode 100644
index 00000000..ac18893f
--- /dev/null
+++ b/manual/working/commonGuide/database/Databases.md
@@ -0,0 +1,7 @@
+
+# Databases
+
+This section covers a some topics related to working with databases in Play. There is language-specific documentation about working with databases in the [[Java|JavaDatabase]] and [[Scala|ScalaDatabase]] guides.
+
+- [[Using an in memory H2 database|Developing-with-the-H2-Database]]
+- [[Managing database evolutions|Evolutions]]
diff --git a/manual/detailedTopics/database/Developing-with-the-H2-Database.md b/manual/working/commonGuide/database/Developing-with-the-H2-Database.md
similarity index 68%
rename from manual/detailedTopics/database/Developing-with-the-H2-Database.md
rename to manual/working/commonGuide/database/Developing-with-the-H2-Database.md
index 1e0935c1..4939f1a2 100644
--- a/manual/detailedTopics/database/Developing-with-the-H2-Database.md
+++ b/manual/working/commonGuide/database/Developing-with-the-H2-Database.md
@@ -1,7 +1,13 @@
-
+
# H2 database
-The H2 in memory database is very convenient for development because your evolutions are run from scratch when play is restarted. If you are using anorm you probably need it to closely mimic your planned production database. To tell h2 that you want to mimic a particular database you add a parameter to the database url in your application.conf file, for example:
+> **Note:** From Play 2.6.x onwards you actually need to include the H2 Dependency on your own. To do this you just need to add the following to your build.sbt:
+>
+> ```
+> libraryDependencies += "com.h2database" % "h2" % "1.4.192"
+> ```
+
+The H2 in memory database is very convenient for development because your evolutions are run from scratch when play is restarted. If you are using Anorm, you probably need it to closely mimic your planned production database. To tell h2 that you want to mimic a particular database you add a parameter to the database url in your application.conf file, for example:
```
db.default.url="jdbc:h2:mem:play;MODE=MYSQL"
@@ -60,13 +66,15 @@ db.default.url="jdbc:h2:mem:play;MODE=MYSQL"
H2, by default, drops your in memory database if there are no connections to it anymore. You probably don't want this to happen. To prevent this add `DB_CLOSE_DELAY=-1` to the url (use a semicolon as a separator) eg: `jdbc:h2:mem:play;MODE=MYSQL;DB_CLOSE_DELAY=-1`
+> **Note:** Play's builtin JDBC Module will automatically add `DB_CLOSE_DELAY=-1`, however if you are using play-slick with evolutions you need to manually add `;DB_CLOSE_DELAY=-1` to your database url, else the evolution will be in a endless loop since the play application will restart after the evolutions are run, so that the applied evolutions will directly be lost.
+
## Caveats
H2, by default, creates tables with upper case names. Sometimes you don't want this to happen, for example when using H2 with Play evolutions in some compatibility modes. To prevent this add `DATABASE_TO_UPPER=FALSE` to the url (use a semicolon as a separator) eg: `jdbc:h2:mem:play;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=FALSE`
## H2 Browser
-You can browse the contents of your database by typing `h2-browser` at the play console. An SQL browser will run in your web browser.
+You can browse the contents of your database by typing `h2-browser` at the [sbt shell](https://www.scala-sbt.org/0.13/docs/Howto-Interactive-Mode.html). An SQL browser will run in your web browser.
## H2 Documentation
diff --git a/manual/detailedTopics/evolutions/Evolutions.md b/manual/working/commonGuide/database/Evolutions.md
similarity index 79%
rename from manual/detailedTopics/evolutions/Evolutions.md
rename to manual/working/commonGuide/database/Evolutions.md
index a93c3819..8716e1d6 100644
--- a/manual/detailedTopics/evolutions/Evolutions.md
+++ b/manual/working/commonGuide/database/Evolutions.md
@@ -1,4 +1,4 @@
-
+
# Managing database evolutions
When you use a relational database, you need a way to track and organize your database schema evolutions. Typically there are several situations where you need a more sophisticated way to track your database schema changes:
@@ -9,12 +9,20 @@ When you use a relational database, you need a way to track and organize your da
## Enable evolutions
-Add `evolutions` into your dependencies list. For example, in `build.sbt`:
+Add `evolutions` and `jdbc` into your dependencies list. For example, in `build.sbt`:
```scala
-libraryDependencies += evolutions
+libraryDependencies ++= Seq(evolutions, jdbc)
```
+### Running evolutions using compile-time DI
+
+If you are using [[compile-time dependency injection|ScalaCompileTimeDependencyInjection]], you will need to mix in the `EvolutionsComponents` trait to your cake to get access to the `ApplicationEvolutions`, which will run the evolutions when instantiated. `EvolutionsComponents` requires `dbApi` to be defined, which you can get by mixing in `DBComponents` and `HikariCPComponents` (or `BoneCPComponents` if you are using BoneCP instead). Since `applicationEvolutions` is a lazy val supplied by `EvolutionsComponents`, you need to access that val to make sure the evolutions run. For example you could explicitly access it in your `ApplicationLoader`, or have an explicit dependency from another component.
+
+Your models will need an instance of `Database` to make connections to your database, which can be obtained from `dbApi.database`.
+
+@[compile-time-di-evolutions](code/CompileTimeDIEvolutions.scala)
+
## Evolutions scripts
Play tracks your database evolutions using several evolutions script. These scripts are written in plain old SQL and should be located in the `conf/evolutions/{database name}` directory of your application. If the evolutions apply to your default database, this path is `conf/evolutions/default`.
@@ -30,9 +38,9 @@ For example, take a look at this first evolution script that bootstrap a basic a
```
# Users schema
-
+
# --- !Ups
-
+
CREATE TABLE User (
id bigint(20) NOT NULL AUTO_INCREMENT,
email varchar(255) NOT NULL,
@@ -41,9 +49,9 @@ CREATE TABLE User (
isAdmin boolean NOT NULL,
PRIMARY KEY (id)
);
-
+
# --- !Downs
-
+
DROP TABLE User;
```
@@ -53,7 +61,7 @@ As you see you have to delimit the both Ups and Downs section by using comments
Evolutions are automatically activated if a database is configured in `application.conf` and evolution scripts are present. You can disable them by setting `play.evolutions.enabled=false`. For example when tests set up their own database you can disable evolutions for the test environment.
-When evolutions are activated, Play will check your database schema state before each request in DEV mode, or before starting the application in PROD mode. In DEV mode, if your database schema is not up to date, an error page will suggest that you synchronise your database schema by running the appropriate SQL script.
+When evolutions are activated, Play will check your database schema state before each request in DEV mode, or before starting the application in PROD mode. In DEV mode, if your database schema is not up to date, an error page will suggest that you synchronize your database schema by running the appropriate SQL script.
[[images/evolutions.png]]
@@ -64,6 +72,7 @@ If you agree with the SQL script, you can apply it directly by clicking on the
Evolutions can be configured both globally and per datasource. For global configuration, keys should be prefixed with `play.evolutions`. For per datasource configuration, keys should be prefixed with `play.evolutions.db.`, for example `play.evolutions.db.default`. The following configuration options are supported:
* `enabled` - Whether evolutions are enabled. If configured globally to be false, it disables the evolutions module altogether. Defaults to true.
+* `schema` - Database schema in which the generated evolution and lock tables will be saved to. No schema is set by default.
* `autocommit` - Whether autocommit should be used. If false, evolutions will be applied in a single transaction. Defaults to true.
* `useLocks` - Whether a locks table should be used. This must be used if you have many Play nodes that may potentially run evolutions, but you want to ensure that only one does. It will create a table called `play_evolutions_lock`, and use a `SELECT FOR UPDATE NOWAIT` or `SELECT FOR UPDATE` to lock it. This will only work for Postgres, Oracle, and MySQL InnoDB. It will not work for other databases. Defaults to false.
* `autoApply` - Whether evolutions should be automatically applied. In dev mode, this will cause both ups and downs evolutions to be automatically applied. In prod mode, it will cause only ups evolutions to be automatically applied. Defaults to false.
@@ -73,11 +82,11 @@ For example, to enable `autoApply` for all evolutions, you might set `play.evolu
## Synchronizing concurrent changes
-Now let’s imagine that we have two developers working on this project. Developer A will work on a feature that requires a new database table. So he will create the following `2.sql` evolution script:
+Now let’s imagine that we have two developers working on this project. Jamie will work on a feature that requires a new database table. So Jamie will create the following `2.sql` evolution script:
```
# Add Post
-
+
# --- !Ups
CREATE TABLE Post (
id bigint(20) NOT NULL AUTO_INCREMENT,
@@ -88,26 +97,26 @@ CREATE TABLE Post (
FOREIGN KEY (author_id) REFERENCES User(id),
PRIMARY KEY (id)
);
-
+
# --- !Downs
DROP TABLE Post;
```
-Play will apply this evolution script to Developer A’s database.
+Play will apply this evolution script to Jamie’s database.
-On the other hand, developer B will work on a feature that requires altering the User table. So he will also create the following `2.sql` evolution script:
+On the other hand, Robin will work on a feature that requires altering the User table. So Robin will also create the following `2.sql` evolution script:
```
# Update User
-
+
# --- !Ups
ALTER TABLE User ADD age INT;
-
+
# --- !Downs
ALTER TABLE User DROP age;
```
-Developer B finishes his feature and commits (let’s say they are using Git). Now developer A has to merge the his colleague’s work before continuing, so he runs git pull, and the merge has a conflict, like:
+Robin finishes the feature and commits (let’s say by using Git). Now Jamie has to merge Robin’s work before continuing, so Jamie runs git pull, and the merge has a conflict, like:
```
Auto-merging db/evolutions/2.sql
@@ -115,12 +124,12 @@ CONFLICT (add/add): Merge conflict in db/evolutions/2.sql
Automatic merge failed; fix conflicts and then commit the result.
```
-Each developer has created a `2.sql` evolution script. So developer A needs to merge the contents of this file:
+Each developer has created a `2.sql` evolution script. So Jamie needs to merge the contents of this file:
```
<<<<<<< HEAD
# Add Post
-
+
# --- !Ups
CREATE TABLE Post (
id bigint(20) NOT NULL AUTO_INCREMENT,
@@ -131,15 +140,15 @@ CREATE TABLE Post (
FOREIGN KEY (author_id) REFERENCES User(id),
PRIMARY KEY (id)
);
-
+
# --- !Downs
DROP TABLE Post;
=======
# Update User
-
+
# --- !Ups
ALTER TABLE User ADD age INT;
-
+
# --- !Downs
ALTER TABLE User DROP age;
>>>>>>> devB
@@ -149,10 +158,10 @@ The merge is really easy to do:
```
# Add Post and update User
-
+
# --- !Ups
ALTER TABLE User ADD age INT;
-
+
CREATE TABLE Post (
id bigint(20) NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL,
@@ -162,16 +171,16 @@ CREATE TABLE Post (
FOREIGN KEY (author_id) REFERENCES User(id),
PRIMARY KEY (id)
);
-
+
# --- !Downs
ALTER TABLE User DROP age;
-
+
DROP TABLE Post;
```
-This evolution script represents the new revision 2 of the database, that is different of the previous revision 2 that developer A has already applied.
+This evolution script represents the new revision 2 of the database, that is different of the previous revision 2 that Jamie has already applied.
-So Play will detect it and ask developer A to synchronize his database by first reverting the old revision 2 already applied, and by applying the new revision 2 script:
+So Play will detect it and ask Jamie to synchronize the database by first reverting the old revision 2 already applied, and by applying the new revision 2 script:
## Inconsistent states
@@ -181,10 +190,10 @@ For example, the Ups script of this evolution has an error:
```
# Add another column to User
-
+
# --- !Ups
ALTER TABLE Userxxx ADD company varchar(255);
-
+
# --- !Downs
ALTER TABLE User DROP company;
```
@@ -205,10 +214,10 @@ But because your evolution script has errors, you probably want to fix it. So yo
```
# Add another column to User
-
+
# --- !Ups
ALTER TABLE User ADD company varchar(255);
-
+
# --- !Downs
ALTER TABLE User DROP company;
```
diff --git a/manual/working/commonGuide/database/code/CompileTimeDIEvolutions.scala b/manual/working/commonGuide/database/code/CompileTimeDIEvolutions.scala
new file mode 100644
index 00000000..aa15a6b7
--- /dev/null
+++ b/manual/working/commonGuide/database/code/CompileTimeDIEvolutions.scala
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+//#compile-time-di-evolutions
+import play.api.ApplicationLoader.Context
+import play.api.BuiltInComponentsFromContext
+import play.api.db.Database
+import play.api.db.DBComponents
+import play.api.db.HikariCPComponents
+import play.api.db.evolutions.EvolutionsComponents
+import play.api.routing.Router
+import play.filters.HttpFiltersComponents
+
+class AppComponents(cntx: Context)
+ extends BuiltInComponentsFromContext(cntx)
+ with DBComponents
+ with EvolutionsComponents
+ with HikariCPComponents
+ with HttpFiltersComponents {
+ // this will actually run the database migrations on startup
+ applicationEvolutions
+
+ //###skip: 1
+ val router = Router.empty
+}
+//#compile-time-di-evolutions
diff --git a/manual/detailedTopics/evolutions/images/evolutions.png b/manual/working/commonGuide/database/images/evolutions.png
similarity index 100%
rename from manual/detailedTopics/evolutions/images/evolutions.png
rename to manual/working/commonGuide/database/images/evolutions.png
diff --git a/manual/detailedTopics/evolutions/images/evolutionsError.png b/manual/working/commonGuide/database/images/evolutionsError.png
similarity index 100%
rename from manual/detailedTopics/evolutions/images/evolutionsError.png
rename to manual/working/commonGuide/database/images/evolutionsError.png
diff --git a/manual/working/commonGuide/database/index.toc b/manual/working/commonGuide/database/index.toc
new file mode 100644
index 00000000..5aa80355
--- /dev/null
+++ b/manual/working/commonGuide/database/index.toc
@@ -0,0 +1,3 @@
+Databases:Databases
+Developing-with-the-H2-Database:Using an in memory H2 database
+Evolutions:Managing database evolutions
\ No newline at end of file
diff --git a/manual/working/commonGuide/filters/AllowedHostsFilter.md b/manual/working/commonGuide/filters/AllowedHostsFilter.md
new file mode 100644
index 00000000..abbe834f
--- /dev/null
+++ b/manual/working/commonGuide/filters/AllowedHostsFilter.md
@@ -0,0 +1,43 @@
+
+# Allowed hosts filter
+
+Play provides a filter that lets you configure which hosts can access your application. This is useful to prevent cache poisoning attacks. For a detailed description of how this attack works, see [this blog post](https://www.skeletonscribe.net/2013/05/practical-http-host-header-attacks.html). The filter introduces a whitelist of allowed hosts and sends a 400 (Bad Request) response to all requests with a host that do not match the whitelist.
+
+This is an important filter to use even in development, because DNS rebinding attacks can be used against a developer's instance of Play: see [Rails Webconsole DNS Rebinding](https://benmmurphy.github.io/blog/2016/07/11/rails-webconsole-dns-rebinding/) for an example of how short lived DNS rebinding can attack a server running on localhost.
+
+Note that if you are running a functional test against a Play application which has the AllowedHostsFilter, then `FakeRequest` and `Helpers.fakeRequest()` will create a request which already has `HOST` set to `localhost`.
+
+## Enabling the allowed hosts filter
+
+> **Note:** As of Play 2.6.x, the Allowed Hosts filter is included in Play's list of default filters that are applied automatically to projects. See [[the Filters page|Filters]] for more information.
+
+To enable the filter manually, add the allowed hosts filter to your filters in `application.conf`:
+
+```
+play.filters.enabled += play.filters.hosts.AllowedHostsFilter
+```
+
+## Configuring allowed hosts
+
+You can configure which hosts the filter allows using `application.conf`. See the Play filters [`reference.conf`](resources/confs/filters-helpers/reference.conf) to see the defaults.
+
+`play.filters.hosts.allowed` is a list of strings of the form `.example.com` or `example.com`. With a leading dot, the pattern will match example.com and all subdomains (`www.example.com`, `foo.example.com`, `foo.bar.example.com`, etc.). Without the leading dot it will just match the exact domain. If your application runs on a specific port, you can also include a port number, for instance `.example.com:8080`.
+
+You can use the `.` pattern to match all hosts (not recommended in production). Note that the filter also strips the dot character from the end of the host, so the `example.com` pattern will match `example.com.`
+
+An example configuration follows.
+
+```
+play.filters.hosts {
+ # Allow requests to example.com, its subdomains, and localhost:9000.
+ allowed = [".example.com", "localhost:9000"]
+}
+```
+
+## Testing
+
+Because the AllowedHostsFilter filter is added automatically, functional tests need to have the Host HTTP header added.
+
+If you are using `FakeRequest` or `Helpers.fakeRequest`, then the `Host` HTTP header is added for you automatically. If you are using `play.mvc.Http.RequestBuilder`, then you may need to add your own line to add the header manually:
+
+@[test-with-request-builder](code/javaguide/detailed/filters/FiltersTest.java)
diff --git a/manual/working/commonGuide/filters/CorsFilter.md b/manual/working/commonGuide/filters/CorsFilter.md
new file mode 100644
index 00000000..0f02c531
--- /dev/null
+++ b/manual/working/commonGuide/filters/CorsFilter.md
@@ -0,0 +1,41 @@
+
+# Cross-Origin Resource Sharing
+
+Play provides a filter that implements Cross-Origin Resource Sharing (CORS).
+
+CORS is a protocol that allows web applications to make requests from the browser across different domains. A full specification can be found [here](http://www.w3.org/TR/cors/).
+
+## Enabling the CORS filter
+
+To enable the CORS filter, add `play.filters.cors.CORSFilter` to `application.conf`:
+
+```
+play.filters.enabled += "play.filters.cors.CORSFilter"
+```
+
+## Configuring the CORS filter
+
+The filter can be configured from `application.conf`. For a full listing of configuration options, see the Play filters [`reference.conf`](resources/confs/filters-helpers/reference.conf).
+
+The available options include:
+
+* `play.filters.cors.pathPrefixes` - filter paths by a whitelist of path prefixes
+* `play.filters.cors.allowedOrigins` - allow only requests with origins from a whitelist (by default all origins are allowed)
+* `play.filters.cors.allowedHttpMethods` - allow only HTTP methods from a whitelist for preflight requests (by default all methods are allowed)
+* `play.filters.cors.allowedHttpHeaders` - allow only HTTP headers from a whitelist for preflight requests (by default all headers are allowed)
+* `play.filters.cors.exposedHeaders` - set custom HTTP headers to be exposed in the response (by default no headers are exposed)
+* `play.filters.cors.supportsCredentials` - disable/enable support for credentials (by default credentials support is enabled)
+* `play.filters.cors.preflightMaxAge` - set how long the results of a preflight request can be cached in a preflight result cache (by default 1 hour)
+* `play.filters.cors.serveForbiddenOrigins` - enable/disable serving requests with origins not in whitelist as non-CORS requests (by default they are forbidden)
+
+For example:
+
+```
+play.filters.cors {
+ pathPrefixes = ["/some/path", ...]
+ allowedOrigins = ["http://www.example.com", ...]
+ allowedHttpMethods = ["GET", "POST"]
+ allowedHttpHeaders = ["Accept"]
+ preflightMaxAge = 3 days
+}
+```
diff --git a/manual/working/commonGuide/filters/Filters.md b/manual/working/commonGuide/filters/Filters.md
new file mode 100644
index 00000000..13eb83cc
--- /dev/null
+++ b/manual/working/commonGuide/filters/Filters.md
@@ -0,0 +1,135 @@
+
+# Built-in HTTP filters
+
+Play provides several standard filters that can modify the HTTP behavior of your application. You can also write your own filters in either [[Java|JavaHttpFilters]] or [[Scala|ScalaHttpFilters]].
+
+- [[Configuring gzip encoding|GzipEncoding]]
+- [[Configuring security headers|SecurityHeaders]]
+- [[Configuring CORS|CorsFilter]]
+- [[Configuring allowed hosts|AllowedHostsFilter]]
+- [[Configuring Redirect HTTPS filter|RedirectHttpsFilter]]
+
+## Default Filters
+
+Play now comes with a default set of enabled filters, defined through configuration. If the property `play.http.filters` is null, then the default is now `play.api.http.EnabledFilters`, which loads up the filters defined by fully qualified class name in the `play.filters.enabled` configuration property.
+
+In Play itself, `play.filters.enabled` is an empty list. However, the filters library is automatically loaded in sbt as an AutoPlugin called `PlayFilters`, and will append the following values to the `play.filters.enabled` property:
+
+* `play.filters.csrf.CSRFFilter`
+* `play.filters.headers.SecurityHeadersFilter`
+* `play.filters.hosts.AllowedHostsFilter`
+
+This means that on new projects, CSRF protection ([[ScalaCsrf]] / [[JavaCsrf]]), [[SecurityHeaders]] and [[AllowedHostsFilter]] are all defined automatically.
+
+To append to the defaults list, use the `+=`:
+
+```
+play.filters.enabled+=MyFilter
+```
+
+If you have previously defined your own filters by extending `play.api.http.DefaultHttpFilters`, then you can also combine `EnabledFilters` with your own filters in code:
+
+Java
+: @[filters-combine-enabled-filters](code/javaguide/detailed/filters/Filters.java)
+
+Scala
+: @[filters-combine-enabled-filters](code/scalaguide/detailed/filters/ScalaFilters.scala)
+
+Otherwise, if you have a `Filters` class in the root or have `play.http.filters` defined explicitly, it will take precedence over the `EnabledFilters` functionality described below.
+
+### Testing Default Filters
+
+Because there are several filters enabled, functional tests may need to change slightly to ensure that all the tests pass and requests are valid. For example, a request that does not have a `Host` HTTP header set to `localhost` will not pass the AllowedHostsFilter and will return a 400 Forbidden response instead.
+
+#### Testing with AllowedHostsFilter
+
+Because the AllowedHostsFilter filter is added automatically, functional tests need to have the Host HTTP header added.
+
+If you are using `FakeRequest` or `Helpers.fakeRequest`, then the `Host` HTTP header is added for you automatically. If you are using `play.mvc.Http.RequestBuilder`, then you may need to add your own line to add the header manually:
+
+@[test-with-request-builder](code/javaguide/detailed/filters/FiltersTest.java)
+
+#### Testing with CSRFFilter
+
+Because the CSRFFilter filter is added automatically, tests that render a Twirl template that includes `CSRF.formField`, i.e.
+
+```html
+@(userForm: Form[UserData])(implicit request: RequestHeader, m: Messages)
+
+user form
+
+@request.flash.get("success").getOrElse("")
+
+@helper.form(action = routes.UserController.userPost()) {
+ @helper.CSRF.formField
+ @helper.inputText(userForm("name"))
+ @helper.inputText(userForm("age"))
+
+}
+```
+
+must contain a CSRF token in the request. In the Scala API, this is done by importing `play.api.test.CSRFTokenHelper._`, which enriches `play.api.test.FakeRequest` with the `withCSRFToken` method:
+
+@[test-with-withCSRFToken](code/scalaguide/detailed/filters/UserControllerSpec.scala)
+
+In the Java API, this is done by calling `CSRFTokenHelper.addCSRFToken` on a `play.mvc.Http.RequestBuilder` instance:
+
+@[test-with-addCSRFToken](code/javaguide/detailed/filters/FiltersTest.java)
+
+### Disabling Default Filters
+
+The simplest way to disable a filter is to add it to the `play.filters.disabled` list in `application.conf`:
+
+```
+play.filters.disabled+=play.filters.hosts.AllowedHostsFilter
+```
+
+This may be useful if you have functional tests that you do not want to go through the default filters.
+
+To remove the default filters, you can set the entire list manually:
+
+```
+play.filters.enabled=[]
+```
+
+If you want to remove all filter classes, you can disable it through the `disablePlugins` mechanism:
+
+```
+lazy val root = project.in(file(".")).enablePlugins(PlayScala).disablePlugins(PlayFilters)
+```
+
+If you are writing functional tests involving `GuiceApplicationBuilder`, then you can disable all filters in a test by calling `configure`:
+
+@[test-disabling-filters](code/scalaguide/detailed/filters/UserControllerSpec.scala)
+
+## Compile Time Default Filters
+
+If you are using compile time dependency injection, then the default filters are resolved at compile time, rather than through runtime.
+
+This means that the [`play.api.BuiltInComponents`](api/scala/play/api/BuiltInComponents.html) trait (for Scala) and [`play.BuiltInComponents`](api/java/play/BuiltInComponents.html) interface (for Java) now contains an `httpFilters` method which is left abstract. The default list of filters is defined in [`play.filters.HttpFiltersComponents`](api/scala/play/filters/HttpFiltersComponents.html) for Scala and [`play.filters.components.HttpFiltersComponents`](api/java/play/filters/components/HttpFiltersComponents.html) for Java. So, for most cases you will want to mixin `HttpFiltersComponents` and append your own filters:
+
+Java
+: @[appending-filters-compile-time-di](code/javaguide/detailed/filters/add/MyAppComponents.java)
+
+Scala
+: @[appending-filters-compile-time-di](code/scalaguide/detailed/filters/FiltersComponents.scala)
+
+If you want to filter elements out of the list, you can do the following:
+
+Java
+: @[removing-filters-compile-time-di](code/javaguide/detailed/filters/remove/MyAppComponents.java)
+
+Scala
+: @[removing-filters-compile-time-di](code/scalaguide/detailed/filters/FiltersComponents.scala)
+
+### Disabling Compile Time Default Filters
+
+To disable the default filters, mix in [`play.api.NoHttpFiltersComponents`](api/scala/play/api/NoHttpFiltersComponents.html) for Scala and [`play.filters.components.NoHttpFiltersComponents`](api/java/play/filters/components/NoHttpFiltersComponents.html) for Java:
+
+Java
+: @[remove-all-filters-compile-time-di](code/javaguide/detailed/filters/removeAll/MyAppComponents.java)
+
+Scala
+: @[remove-all-filters-compile-time-di](code/scalaguide/detailed/filters/FiltersComponents.scala)
+
+Both Scala [`play.api.NoHttpFiltersComponents`](api/scala/play/api/NoHttpFiltersComponents.html) and [`play.filters.components.NoHttpFiltersComponents`](api/java/play/filters/components/NoHttpFiltersComponents.html) have `httpFilters` method which returns an empty list of filters.
\ No newline at end of file
diff --git a/manual/working/commonGuide/filters/GzipEncoding.md b/manual/working/commonGuide/filters/GzipEncoding.md
new file mode 100644
index 00000000..a842a06e
--- /dev/null
+++ b/manual/working/commonGuide/filters/GzipEncoding.md
@@ -0,0 +1,45 @@
+
+# Configuring gzip encoding
+
+Play provides a gzip filter that can be used to gzip responses.
+
+## Enabling the gzip filter
+
+To enable the gzip filter, add the filter to `application.conf`:
+
+```
+play.filters.enabled += "play.filters.gzip.GzipFilter"
+```
+
+## Configuring the gzip filter
+
+The gzip filter supports a small number of tuning configuration options, which can be configured from `application.conf`. To see the available configuration options, see the Play filters [`reference.conf`](resources/confs/filters-helpers/reference.conf).
+
+## Controlling which responses are gzipped
+
+You can control which responses are and aren't gzipped based on their content types via `application.conf`:
+
+```
+play.filters.gzip {
+
+ contentType {
+
+ # If non empty, then a response will only be compressed if its content type is in this list.
+ whiteList = [ "text/*", "application/javascript", "application/json" ]
+
+ # The black list is only used if the white list is empty.
+ # Compress all responses except the ones whose content type is in this list.
+ blackList = []
+ }
+}
+```
+
+As a more flexible alternative you can use the `shouldGzip` parameter of the gzip filter itself, which accepts a function of a request header and a response header to a boolean.
+
+For example, the code below only gzips HTML responses:
+
+Scala
+: @[should-gzip](code/GzipEncoding.scala)
+
+Java
+: @[gzip-filter](code/detailedtopics/configuration/gzipencoding/CustomFilters.java)
diff --git a/manual/working/commonGuide/filters/RedirectHttpsFilter.md b/manual/working/commonGuide/filters/RedirectHttpsFilter.md
new file mode 100644
index 00000000..7ccbf556
--- /dev/null
+++ b/manual/working/commonGuide/filters/RedirectHttpsFilter.md
@@ -0,0 +1,55 @@
+
+# Redirect HTTPS Filter
+
+Play provides a filter which will redirect all HTTP requests to HTTPS automatically.
+
+## Enabling the HTTPS filter
+
+To enable the filter, add it to `play.filters.enabled`:
+
+```
+play.filters.enabled += play.filters.https.RedirectHttpsFilter
+```
+
+By default, the redirect only happens in Prod mode. To override this, set `play.filters.https.redirectEnabled = true`.
+
+## Determining Secure Requests
+
+The filter evaluates a request to be secure if `request.secure` is true.
+
+This logic depends on the [[trusted proxies|HTTPServer#configuring-trusted-proxies]] configured for Play's HTTP engine. Internally, `play.core.server.common.ForwardedHeaderHandler` and `play.api.mvc.request.RemoteConnection` determine between them whether an incoming request meets the criteria to be "secure", meaning that the request has gone through HTTPS at some point.
+
+When the filter is enabled, any request that is not secure is redirected.
+
+## Strict Transport Security
+
+The [Strict Transport Security](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) header is used to indicate when HTTPS should always be used, and is added to a secure request. The HSTS header is only added if the redirect is enabled.
+
+The default is "max-age=31536000; includeSubDomains", and can be set explicitly by adding the following to `application.conf`:
+
+```
+play.filters.https.strictTransportSecurity="max-age=31536000; includeSubDomains"
+```
+
+It is also possible to set `play.filters.https.strictTransportSecurity = null` to disable HSTS.
+
+Note that the `Strict-Transport-Security` header tells the browser to prefer HTTPS for *all requests to that hostname*, so if you enable the filter in dev mode, the header will affect other apps being developed with that hostname (e.g. `localhost:9000`). If you want to avoid this, either use a different host for each app in development (`app1:9000`, `app2:9000`, etc.) or disable HSTS completely in dev mode.
+
+## Redirect code
+
+The filter redirects using HTTP code 308, which is a permanent redirect that does not change the HTTP method according to [RFC 7238](https://tools.ietf.org/html/rfc7238). This will work with the vast majority of browsers, but you can change the redirect code if working with older browsers:
+
+```
+play.filters.https.redirectStatusCode = 301
+```
+
+## Custom HTTPS Port
+
+If the HTTPS server is on a custom port, then the redirect URL needs to be aware of it. If the port is specified:
+
+```
+play.filters.https.port = 9443
+```
+
+then the URL in the `Location` header will include the port specifically, e.g. `https://playframework.com:9443/some/url`.
+
diff --git a/manual/working/commonGuide/filters/SecurityHeaders.md b/manual/working/commonGuide/filters/SecurityHeaders.md
new file mode 100644
index 00000000..abb8ab15
--- /dev/null
+++ b/manual/working/commonGuide/filters/SecurityHeaders.md
@@ -0,0 +1,45 @@
+
+# Configuring Security Headers
+
+Play provides a security headers filter that can be used to configure some default headers in the HTTP response to mitigate security issues and provide an extra level of defense for new applications.
+
+## Enabling the security headers filter
+
+> **Note:** As of Play 2.6.x, the Security Headers filter is included in Play's list of default filters that are applied automatically to projects. See [[the Filters page|Filters]] for more information.
+
+To enable the security headers filter manually, add the security headers filter to your filters in `application.conf`:
+
+```
+play.filters.enabled += "play.filters.headers.SecurityHeadersFilter"
+```
+
+## Configuring the security headers
+
+Scaladoc is available in the [play.filters.headers](api/scala/play/filters/headers/index.html) package.
+
+The filter will set headers in the HTTP response automatically. The settings can be configured through the following settings in `application.conf`
+
+* `play.filters.headers.frameOptions` - sets [X-Frame-Options](https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options), "DENY" by default.
+* `play.filters.headers.xssProtection` - sets [X-XSS-Protection](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection), "1; mode=block" by default.
+* `play.filters.headers.contentTypeOptions` - sets [X-Content-Type-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options), "nosniff" by default.
+* `play.filters.headers.permittedCrossDomainPolicies` - sets [X-Permitted-Cross-Domain-Policies](https://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html), "master-only" by default.
+* `play.filters.headers.referrerPolicy` - sets [Referrer Policy](https://www.w3.org/TR/referrer-policy/), "origin-when-cross-origin, strict-origin-when-cross-origin" by default.
+* `play.filters.headers.contentSecurityPolicy` - sets [Content-Security-Policy](https://developers.google.com/web/fundamentals/security/csp/), "default-src 'self'" by default.
+
+Any of the headers can be disabled by setting a configuration value of `null`, for example:
+
+```
+play.filters.headers.frameOptions = null
+```
+
+For a full listing of configuration options, see the Play filters [`reference.conf`](resources/confs/filters-helpers/reference.conf).
+
+## Action-specific overrides
+
+Security headers may be overridden in specific actions using `withHeaders` on the result:
+
+@[allowActionSpecificHeaders](code/SecurityHeaders.scala)
+
+Any security headers not mentioned in `withHeaders` will use the usual configured values
+(if present) or the defaults. Action-specific security headers are ignored unless
+`play.filters.headers.allowActionSpecificHeaders` is set to `true` in the configuration.
diff --git a/manual/working/commonGuide/filters/code/GzipEncoding.scala b/manual/working/commonGuide/filters/code/GzipEncoding.scala
new file mode 100644
index 00000000..69e5bd1d
--- /dev/null
+++ b/manual/working/commonGuide/filters/code/GzipEncoding.scala
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package detailedtopics.configuration.gzipencoding
+
+import akka.stream.ActorMaterializer
+import play.api.test._
+
+class GzipEncoding extends PlaySpecification {
+
+ import javax.inject.Inject
+
+ import play.api.http.DefaultHttpFilters
+ import play.filters.gzip.GzipFilter
+
+ class Filters @Inject()(gzipFilter: GzipFilter) extends DefaultHttpFilters(gzipFilter)
+
+ "gzip filter" should {
+
+ "allow custom strategies for when to gzip (Scala)" in {
+
+ import play.api.mvc._
+ running() { app =>
+ implicit val mat = ActorMaterializer()(app.actorSystem)
+ def Action = app.injector.instanceOf[DefaultActionBuilder]
+
+ val filter =
+ //#should-gzip
+ new GzipFilter(
+ shouldGzip = (request, response) => response.body.contentType.exists(_.startsWith("text/html"))
+ )
+ //#should-gzip
+
+ header(CONTENT_ENCODING, filter(Action(Results.Ok("foo")))(gzipRequest).run()) must beNone
+ }
+ }
+
+ "allow custom strategies for when to gzip (Java)" in {
+
+ import play.api.mvc._
+ val app = play.api.inject.guice.GuiceApplicationBuilder().build()
+ running(app) {
+ implicit val mat = ActorMaterializer()(app.actorSystem)
+ def Action = app.injector.instanceOf[DefaultActionBuilder]
+
+ val filter = (new CustomFilters(mat)).getFilters.get(0)
+
+ header(CONTENT_ENCODING, filter(Action(Results.Ok("foo")))(gzipRequest).run()) must beNone
+ }
+ }
+
+ }
+
+ def gzipRequest = FakeRequest().withHeaders(ACCEPT_ENCODING -> "gzip")
+
+}
diff --git a/manual/working/commonGuide/filters/code/SecurityHeaders.scala b/manual/working/commonGuide/filters/code/SecurityHeaders.scala
new file mode 100644
index 00000000..435de7bf
--- /dev/null
+++ b/manual/working/commonGuide/filters/code/SecurityHeaders.scala
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package detailedtopics.configuration.securityheaders
+
+//#filters
+import javax.inject.Inject
+
+import play.api.http.DefaultHttpFilters
+import play.filters.headers.SecurityHeadersFilter
+import play.api.mvc.BaseController
+import play.api.mvc.ControllerComponents
+//#filters
+
+class SecurityHeaders @Inject()(val controllerComponents: ControllerComponents) extends BaseController {
+
+ def index = Action {
+ //#allowActionSpecificHeaders
+ Ok("Index").withHeaders(SecurityHeadersFilter.CONTENT_SECURITY_POLICY_HEADER -> "my page-specific header")
+ //#allowActionSpecificHeaders
+ }
+}
+
+object SecurityHeaders {
+ class Filters @Inject()(securityHeadersFilter: SecurityHeadersFilter)
+ extends DefaultHttpFilters(securityHeadersFilter)
+}
diff --git a/manual/working/commonGuide/filters/code/detailedtopics/configuration/gzipencoding/CustomFilters.java b/manual/working/commonGuide/filters/code/detailedtopics/configuration/gzipencoding/CustomFilters.java
new file mode 100644
index 00000000..edff7749
--- /dev/null
+++ b/manual/working/commonGuide/filters/code/detailedtopics/configuration/gzipencoding/CustomFilters.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package detailedtopics.configuration.gzipencoding;
+
+import akka.stream.Materializer;
+import play.mvc.EssentialFilter;
+import play.filters.gzip.GzipFilter;
+import play.filters.gzip.GzipFilterConfig;
+import play.http.HttpFilters;
+import play.mvc.Http;
+import play.mvc.Result;
+
+import javax.inject.Inject;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.BiFunction;
+
+public class CustomFilters implements HttpFilters {
+
+ private List filters;
+
+ @Inject
+ public CustomFilters(Materializer materializer) {
+ // #gzip-filter
+ GzipFilterConfig gzipFilterConfig = new GzipFilterConfig();
+ GzipFilter gzipFilter =
+ new GzipFilter(
+ gzipFilterConfig.withShouldGzip(
+ (BiFunction)
+ (req, res) -> res.body().contentType().orElse("").startsWith("text/html")),
+ materializer);
+ // #gzip-filter
+ filters = Collections.singletonList(gzipFilter.asJava());
+ }
+
+ @Override
+ public List getFilters() {
+ return filters;
+ }
+}
diff --git a/manual/working/commonGuide/filters/code/filters.sbt b/manual/working/commonGuide/filters/code/filters.sbt
new file mode 100644
index 00000000..94592fb2
--- /dev/null
+++ b/manual/working/commonGuide/filters/code/filters.sbt
@@ -0,0 +1,7 @@
+//
+// Copyright (C) 2009-2019 Lightbend Inc.
+//
+
+//#content
+libraryDependencies += filters
+//#content
diff --git a/manual/working/commonGuide/filters/code/javaguide/detailed/filters/Filters.java b/manual/working/commonGuide/filters/code/javaguide/detailed/filters/Filters.java
new file mode 100644
index 00000000..b5265233
--- /dev/null
+++ b/manual/working/commonGuide/filters/code/javaguide/detailed/filters/Filters.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package javaguide.detailed.filters;
+
+// #filters-combine-enabled-filters
+import play.api.http.EnabledFilters;
+import play.filters.cors.CORSFilter;
+import play.http.DefaultHttpFilters;
+import play.mvc.EssentialFilter;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class Filters extends DefaultHttpFilters {
+
+ @Inject
+ public Filters(EnabledFilters enabledFilters, CORSFilter corsFilter) {
+ super(combine(enabledFilters.asJava().getFilters(), corsFilter.asJava()));
+ }
+
+ private static List combine(
+ List filters, EssentialFilter toAppend) {
+ List combinedFilters = new ArrayList<>(filters);
+ combinedFilters.add(toAppend);
+ return combinedFilters;
+ }
+}
+// #filters-combine-enabled-filters
diff --git a/manual/working/commonGuide/filters/code/javaguide/detailed/filters/FiltersTest.java b/manual/working/commonGuide/filters/code/javaguide/detailed/filters/FiltersTest.java
new file mode 100644
index 00000000..efe00271
--- /dev/null
+++ b/manual/working/commonGuide/filters/code/javaguide/detailed/filters/FiltersTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package javaguide.detailed.filters;
+
+import org.junit.Test;
+import play.api.mvc.PlayBodyParsers;
+import play.api.test.CSRFTokenHelper;
+import play.core.j.JavaContextComponents;
+import play.mvc.Http;
+import play.mvc.Results;
+import play.routing.Router;
+import play.routing.RoutingDsl;
+import play.test.Helpers;
+import play.test.WithApplication;
+
+import static play.test.Helpers.GET;
+import static play.test.Helpers.POST;
+
+public class FiltersTest extends WithApplication {
+
+ @Test
+ public void testRequestBuilder() {
+ Router router =
+ new RoutingDsl(
+ instanceOf(play.mvc.BodyParser.Default.class),
+ instanceOf(JavaContextComponents.class))
+ .GET("/xx/Kiwi")
+ .routeTo(() -> Results.ok("success"))
+ .build();
+
+ // #test-with-request-builder
+ Http.RequestBuilder request =
+ new Http.RequestBuilder()
+ .method(GET)
+ .header(Http.HeaderNames.HOST, "localhost")
+ .uri("/xx/Kiwi");
+ // #test-with-request-builder
+
+ Helpers.routeAndCall(app, router, request, 10_000 /* 10 seconds */);
+ }
+
+ @Test
+ public void test() {
+ Router router =
+ new RoutingDsl(
+ instanceOf(play.mvc.BodyParser.Default.class),
+ instanceOf(JavaContextComponents.class))
+ .POST("/xx/Kiwi")
+ .routeTo(() -> Results.ok("success"))
+ .build();
+
+ // #test-with-addCSRFToken
+ Http.RequestBuilder request = new Http.RequestBuilder().method(POST).uri("/xx/Kiwi");
+
+ request = CSRFTokenHelper.addCSRFToken(request);
+ // #test-with-addCSRFToken
+
+ Helpers.routeAndCall(app, router, request, 10_000 /* 10 seconds */);
+ }
+}
diff --git a/manual/working/commonGuide/filters/code/javaguide/detailed/filters/add/MyAppComponents.java b/manual/working/commonGuide/filters/code/javaguide/detailed/filters/add/MyAppComponents.java
new file mode 100644
index 00000000..caf44b5d
--- /dev/null
+++ b/manual/working/commonGuide/filters/code/javaguide/detailed/filters/add/MyAppComponents.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package javaguide.detailed.filters.add;
+
+import javaguide.application.httpfilters.LoggingFilter;
+
+// #appending-filters-compile-time-di
+import play.ApplicationLoader;
+import play.BuiltInComponentsFromContext;
+import play.filters.components.HttpFiltersComponents;
+import play.mvc.EssentialFilter;
+import play.routing.Router;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MyAppComponents extends BuiltInComponentsFromContext implements HttpFiltersComponents {
+
+ public MyAppComponents(ApplicationLoader.Context context) {
+ super(context);
+ }
+
+ @Override
+ public List httpFilters() {
+ List combinedFilters =
+ new ArrayList<>(HttpFiltersComponents.super.httpFilters());
+ combinedFilters.add(new LoggingFilter(materializer()));
+ return combinedFilters;
+ }
+
+ @Override
+ public Router router() {
+ return Router.empty(); // implement the router as needed
+ }
+}
+// #appending-filters-compile-time-di
diff --git a/manual/working/commonGuide/filters/code/javaguide/detailed/filters/remove/MyAppComponents.java b/manual/working/commonGuide/filters/code/javaguide/detailed/filters/remove/MyAppComponents.java
new file mode 100644
index 00000000..55300d83
--- /dev/null
+++ b/manual/working/commonGuide/filters/code/javaguide/detailed/filters/remove/MyAppComponents.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package javaguide.detailed.filters.remove;
+
+import play.ApplicationLoader;
+import play.BuiltInComponentsFromContext;
+import play.filters.components.HttpFiltersComponents;
+import play.filters.csrf.CSRFFilter;
+import play.mvc.EssentialFilter;
+import play.routing.Router;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+// #removing-filters-compile-time-di
+public class MyAppComponents extends BuiltInComponentsFromContext implements HttpFiltersComponents {
+
+ public MyAppComponents(ApplicationLoader.Context context) {
+ super(context);
+ }
+
+ @Override
+ public List httpFilters() {
+ return HttpFiltersComponents.super.httpFilters().stream()
+ .filter(filter -> !filter.getClass().equals(CSRFFilter.class))
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public Router router() {
+ return Router.empty(); // implement the router as needed
+ }
+}
+// #removing-filters-compile-time-di
diff --git a/manual/working/commonGuide/filters/code/javaguide/detailed/filters/removeAll/MyAppComponents.java b/manual/working/commonGuide/filters/code/javaguide/detailed/filters/removeAll/MyAppComponents.java
new file mode 100644
index 00000000..3d274ff3
--- /dev/null
+++ b/manual/working/commonGuide/filters/code/javaguide/detailed/filters/removeAll/MyAppComponents.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package javaguide.detailed.filters.removeAll;
+
+import play.ApplicationLoader;
+import play.BuiltInComponentsFromContext;
+import play.filters.components.NoHttpFiltersComponents;
+import play.routing.Router;
+
+// #remove-all-filters-compile-time-di
+public class MyAppComponents extends BuiltInComponentsFromContext
+ implements NoHttpFiltersComponents {
+
+ public MyAppComponents(ApplicationLoader.Context context) {
+ super(context);
+ }
+
+ // no need to override httpFilters method
+
+ @Override
+ public Router router() {
+ return Router.empty(); // implement the router as needed
+ }
+}
+// #remove-all-filters-compile-time-di
diff --git a/manual/working/commonGuide/filters/code/scalaguide/detailed/filters/FiltersComponents.scala b/manual/working/commonGuide/filters/code/scalaguide/detailed/filters/FiltersComponents.scala
new file mode 100644
index 00000000..4698bf5d
--- /dev/null
+++ b/manual/working/commonGuide/filters/code/scalaguide/detailed/filters/FiltersComponents.scala
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package scalaguide.detailed.filters
+
+// #appending-filters-compile-time-di
+import akka.util.ByteString
+import play.api.ApplicationLoader
+import play.api.BuiltInComponentsFromContext
+import play.api.NoHttpFiltersComponents
+import play.api.libs.streams.Accumulator
+import play.api.mvc.EssentialAction
+import play.api.mvc.EssentialFilter
+import play.api.mvc.RequestHeader
+import play.api.mvc.Result
+import play.api.routing.Router
+import play.filters.csrf.CSRFFilter
+
+// ###replace: class MyAppComponents(context: ApplicationLoader.Context)
+class AddHttpFiltersComponents(context: ApplicationLoader.Context)
+ extends BuiltInComponentsFromContext(context)
+ with play.filters.HttpFiltersComponents {
+
+ lazy val loggingFilter = new LoggingFilter()
+
+ override def httpFilters: Seq[EssentialFilter] = {
+ super.httpFilters :+ loggingFilter
+ }
+
+ override def router: Router = Router.empty // implement the router as needed
+}
+// #appending-filters-compile-time-di
+
+// #removing-filters-compile-time-di
+// ###replace: class MyAppComponents(context: ApplicationLoader.Context)
+class RemoveHttpFilterComponents(context: ApplicationLoader.Context)
+ extends BuiltInComponentsFromContext(context)
+ with play.filters.HttpFiltersComponents {
+
+ override def httpFilters: Seq[EssentialFilter] = {
+ super.httpFilters.filterNot(_.getClass == classOf[CSRFFilter])
+ }
+
+ override def router: Router = Router.empty // implement the router as needed
+}
+// #removing-filters-compile-time-di
+
+// #remove-all-filters-compile-time-di
+// ###replace: class MyAppComponents(context: ApplicationLoader.Context)
+class RemoveAllHttpFiltersComponents(context: ApplicationLoader.Context)
+ extends BuiltInComponentsFromContext(context)
+ with NoHttpFiltersComponents {
+
+ override def router: Router = Router.empty // implement the router as needed
+
+}
+// #remove-all-filters-compile-time-di
+
+class LoggingFilter extends EssentialFilter {
+ override def apply(next: EssentialAction): EssentialAction = new EssentialAction {
+ override def apply(request: RequestHeader): Accumulator[ByteString, Result] = next(request)
+ }
+}
diff --git a/manual/working/commonGuide/filters/code/scalaguide/detailed/filters/ScalaFilters.scala b/manual/working/commonGuide/filters/code/scalaguide/detailed/filters/ScalaFilters.scala
new file mode 100644
index 00000000..766fd9e3
--- /dev/null
+++ b/manual/working/commonGuide/filters/code/scalaguide/detailed/filters/ScalaFilters.scala
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package scalaguide.detailed.filters
+
+// #filters-combine-enabled-filters
+import javax.inject.Inject
+
+import play.filters.cors.CORSFilter
+import play.api.http.DefaultHttpFilters
+import play.api.http.EnabledFilters
+
+class Filters @Inject()(enabledFilters: EnabledFilters, corsFilter: CORSFilter)
+ extends DefaultHttpFilters(enabledFilters.filters :+ corsFilter: _*)
+
+// #filters-combine-enabled-filters
diff --git a/manual/working/commonGuide/filters/code/scalaguide/detailed/filters/UserControllerSpec.scala b/manual/working/commonGuide/filters/code/scalaguide/detailed/filters/UserControllerSpec.scala
new file mode 100644
index 00000000..b53fc1a1
--- /dev/null
+++ b/manual/working/commonGuide/filters/code/scalaguide/detailed/filters/UserControllerSpec.scala
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009-2019 Lightbend Inc.
+ */
+package scalaguide.detailed.filters
+
+// #test-with-withCSRFToken
+import org.specs2.mutable.Specification
+import play.api.inject.guice.GuiceApplicationBuilder
+import play.api.test.CSRFTokenHelper._
+import play.api.test.Helpers._
+import play.api.test.FakeRequest
+import play.api.test.WithApplication
+
+class UserControllerSpec extends Specification {
+ "UserController GET" should {
+
+ "render the index page from the application" in new WithApplication() {
+
+ val controller = app.injector.instanceOf[UserController]
+ val request = FakeRequest().withCSRFToken
+ val result = controller.userGet().apply(request)
+
+ status(result) must beEqualTo(OK)
+ contentType(result) must beSome("text/html")
+ }
+ }
+}
+// #test-with-withCSRFToken
+
+// #test-disabling-filters
+class UserControllerWithoutFiltersSpec extends Specification {
+ "UserControllerWithoutFiltersSpec GET" should {
+
+ "render the index page from the application" in new WithApplication(
+ GuiceApplicationBuilder().configure("play.http.filters" -> "play.api.http.NoHttpFilters").build()
+ ) {
+
+ val controller = app.injector.instanceOf[UserController]
+ val request = FakeRequest().withCSRFToken
+ val result = controller.userGet().apply(request)
+
+ status(result) must beEqualTo(OK)
+ contentType(result) must beSome("text/html")
+ }
+ }
+}
+// #test-disabling-filters
+
+import javax.inject.Inject
+import play.api.mvc.BaseController
+import play.api.mvc.ControllerComponents
+
+class UserController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {
+ def userGet = Action {
+ Ok("success").as(HTML)
+ }
+}
diff --git a/manual/working/commonGuide/filters/index.toc b/manual/working/commonGuide/filters/index.toc
new file mode 100644
index 00000000..ef336ae1
--- /dev/null
+++ b/manual/working/commonGuide/filters/index.toc
@@ -0,0 +1,6 @@
+Filters:Play HTTP filters
+GzipEncoding:Configuring gzip encoding
+SecurityHeaders:Configuring security headers
+CorsFilter:Configuring CORS
+AllowedHostsFilter:Configuring allowed hosts
+RedirectHttpsFilter:Configuring HTTPS redirect
diff --git a/manual/working/commonGuide/index.toc b/manual/working/commonGuide/index.toc
new file mode 100644
index 00000000..68e71403
--- /dev/null
+++ b/manual/working/commonGuide/index.toc
@@ -0,0 +1,9 @@
+!build:The build system
+!configuration:Configuration
+!assets:Static assets
+!filters:Built-in HTTP filters
+!Modules:Extending Play with modules
+!database:Databases
+!server:Server Backends
+!production:Deploying your application
+!schedule:Scheduling tasks
diff --git a/manual/detailedTopics/production/ConfiguringHttps.md b/manual/working/commonGuide/production/ConfiguringHttps.md
similarity index 85%
rename from manual/detailedTopics/production/ConfiguringHttps.md
rename to manual/working/commonGuide/production/ConfiguringHttps.md
index bc440d06..15eb891f 100644
--- a/manual/detailedTopics/production/ConfiguringHttps.md
+++ b/manual/working/commonGuide/production/ConfiguringHttps.md
@@ -1,4 +1,4 @@
-
+
# Configuring HTTPS
Play can be configured to serve HTTPS. To enable this, simply tell Play which port to listen to using the `https.port` system property. For example:
@@ -15,7 +15,7 @@ HTTPS configuration can either be supplied using system properties or in `applic
By default, Play will generate itself a self-signed certificate, however typically this will not be suitable for serving a website. Play uses Java key stores to configure SSL certificates and keys.
-Signing authorities often provide instructions on how to create a Java keystore (typically with reference to Tomcat configuration). The official Oracle documentation on how to generate keystores using the JDK keytool utility can be found [here](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html). There is also an example in the [[Generating X.509 Certificates|CertificateGeneration]] section.
+Signing authorities often provide instructions on how to create a Java keystore (typically with reference to Tomcat configuration). The official Oracle documentation on how to generate keystores using the JDK keytool utility can be found [here](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html). There is also an example in the [Generating X.509 Certificates](https://lightbend.github.io/ssl-config/CertificateGeneration.html) section.
Having created your keystore, the following configuration properties can be used to configure Play to use it:
@@ -30,11 +30,11 @@ Another alternative to configure the SSL certificates is to provide a custom [SS
#### in Java, an implementation must be provided for [`play.server.SSLEngineProvider`](api/java/play/server/SSLEngineProvider.html)
-@[javaexample](code/java/CustomSSLEngineProvider.java)
+@[javaexample](code/javaguide/CustomSSLEngineProvider.java)
#### in Scala, an implementation must be provided for [`play.server.api.SSLEngineProvider`](api/scala/play/server/api/SSLEngineProvider.html)
-@[scalaexample](code/scala/CustomSSLEngineProvider.scala)
+@[scalaexample](code/scalaguide/CustomSSLEngineProvider.scala)
Having created an implementation for `play.server.SSLEngineProvider` or `play.server.api.SSLEngineProvider`, the following system property configures Play to use it:
@@ -53,7 +53,7 @@ To disable binding on the HTTP port, set the `http.port` system property to be `
## Production usage of HTTPS
-If Play is serving HTTPS in production, it should be running JDK 1.8. JDK 1.8 provides a number of new features that make JSSE feasible as a [TLS termination layer](http://blog.ivanristic.com/2014/03/ssl-tls-improvements-in-java-8.html). If not using JDK 1.8, using a [[reverse proxy|HTTPServer]] in front of Play will give better control and security of HTTPS.
+If Play is serving HTTPS in production, it should be running JDK 1.8. JDK 1.8 provides a number of new features that make JSSE feasible as a [TLS termination layer](https://blog.ivanristic.com/2014/03/ssl-tls-improvements-in-java-8.html). If not using JDK 1.8, using a [[reverse proxy|HTTPServer]] in front of Play will give better control and security of HTTPS.
If you intend to use Play for TLS termination layer, please note the following settings:
diff --git a/manual/working/commonGuide/production/Deploying.md b/manual/working/commonGuide/production/Deploying.md
new file mode 100644
index 00000000..b478e89f
--- /dev/null
+++ b/manual/working/commonGuide/production/Deploying.md
@@ -0,0 +1,268 @@
+
+# Deploying your application
+
+We have seen how to run a Play application in development mode, however the `run` command should not be used to run an application in production mode. When using `run`, on each request, Play checks with sbt to see if any files have changed, and this may have significant performance impacts on your application.
+
+There are several ways to deploy a Play application in production mode. Let's start by using the recommended way, creating a distribution artifact.
+
+## The application secret
+
+Before you run your application in production mode, you need to generate an application secret. To read more about how to do this, see [[Configuring the application secret|ApplicationSecret]]. In the examples below, you will see the use of `-Dplay.http.secret.key=abcdefghijk`. You must generate your own secret to use here.
+
+## Deploying Play with JPA
+ If you are using JPA, you need to take a look at [Deploying with JPA](https://www.playframework.com/documentation/2.6.x/JavaJPA#deploying-play-with-jpa).
+
+## Using the dist task
+
+The `dist` task builds a binary version of your application that you can deploy to a server without any dependency on sbt, the only thing the server needs is a Java installation.
+
+In the Play console, simply type `dist`:
+
+```bash
+[my-first-app] $ dist
+```
+
+And will see something like:
+
+```bash
+$ sbt
+[info] Loading global plugins from /Users/play-developer/.sbt/0.13/plugins
+[info] Loading project definition from /Users/play-developer/my-first-app/project
+[info] Set current project to my-first-app (in build file:/Users/play-developer/my-first-app/)
+[my-first-app] $ dist
+[info] Packaging /Users/play-developer/my-first-app/target/scala-2.11/my-first-app_2.11-1.0-SNAPSHOT-sources.jar ...
+[info] Done packaging.
+[info] Wrote /Users/play-developer/my-first-app/target/scala-2.11/my-first-app_2.11-1.0-SNAPSHOT.pom
+[info] Main Scala API documentation to /Users/play-developer/my-first-app/target/scala-2.11/api...
+[info] Packaging /Users/play-developer/my-first-app/target/scala-2.11/my-first-app_2.11-1.0-SNAPSHOT-web-assets.jar ...
+[info] Done packaging.
+[info] Packaging /Users/play-developer/my-first-app/target/scala-2.11/my-first-app_2.11-1.0-SNAPSHOT.jar ...
+[info] Done packaging.
+model contains 21 documentable templates
+[info] Main Scala API documentation successful.
+[info] Packaging /Users/play-developer/my-first-app/target/scala-2.11/my-first-app_2.11-1.0-SNAPSHOT-javadoc.jar ...
+[info] Done packaging.
+[info] Packaging /Users/play-developer/my-first-app/target/scala-2.11/my-first-app_2.11-1.0-SNAPSHOT-sans-externalized.jar ...
+[info] Done packaging.
+[info]
+[info] Your package is ready in /Users/play-developer/my-first-app/target/universal/my-first-app-1.0-SNAPSHOT.zip
+[info]
+[success] Total time: 5 s, completed Feb 6, 2017 2:08:44 PM
+[my-first-app] $
+```
+
+This produces a ZIP file containing all JAR files needed to run your application in the `target/universal` folder of your application.
+
+To run the application, unzip the file on the target server, and then run the script in the `bin` directory. The name of the script is your application name, and it comes in two versions, a bash shell script, and a windows `.bat` script.
+
+```bash
+$ unzip my-first-app-1.0.zip
+$ my-first-app-1.0/bin/my-first-app -Dplay.http.secret.key=abcdefghijk
+```
+
+You can also specify a different configuration file for a production environment, from the command line:
+
+```bash
+$ my-first-app-1.0/bin/my-first-app -Dconfig.file=/full/path/to/conf/application-prod.conf
+```
+
+For a full description of usage invoke the start script with a `-h` option.
+
+> For Unix users, zip files do not retain Unix file permissions so when the file is expanded the start script will be required to be set as an executable:
+>
+> ```bash
+> $ chmod +x /path/to/bin/
+> ```
+>
+> Alternatively a tar.gz file can be produced instead. Tar files retain permissions. Invoke the `universal:packageZipTarball` task instead of the `dist` task:
+>
+> ```bash
+> sbt universal:packageZipTarball
+> ```
+
+By default, the `dist` task will include the API documentation in the generated package. If this is not necessary, add these lines in `build.sbt`:
+
+@[no-scaladoc](code/production.sbt)
+
+For builds with sub-projects, the statement above has to be applied to all sub-project definitions.
+
+## The Native Packager
+
+Play uses the [sbt Native Packager plugin](https://sbt-native-packager.readthedocs.io/en/v1.3.25/). The native packager plugin declares the `dist` task to create a zip file. Invoking the `dist` task is directly equivalent to invoking the following:
+
+```bash
+[my-first-app] $ universal:packageBin
+```
+
+Many other types of archive can be generated including:
+
+* tar.gz
+* OS X disk images
+* Microsoft Installer (MSI)
+* RPMs
+* Debian packages
+* System V / init.d and Upstart services in RPM/Debian packages
+
+Please consult the [documentation](https://sbt-native-packager.readthedocs.io/en/v1.3.25/) on the native packager plugin for more information.
+
+### Build a server distribution
+
+The sbt-native-packager plugins provides a number archetypes. The one that Play uses by default is called the Java server archetype, which enables the following features:
+
+* System V or Upstart startup scripts
+* [Default folders](https://sbt-native-packager.readthedocs.io/en/v1.3.25/archetypes/java_server/index.html#default-mappings)
+
+More information can be found in the [Java Server Application Archetype documentation](https://sbt-native-packager.readthedocs.io/en/v1.3.25/archetypes/java_server/index.html).
+
+#### Minimal Debian settings
+
+Add the following settings to your build:
+
+@[debian](code/debian.sbt)
+
+Then build your package with:
+
+```bash
+[my-first-app] $ debian:packageBin
+```
+
+#### Minimal RPM settings
+
+Add the following settings to your build:
+
+@[rpm](code/rpm.sbt)
+
+Then build your package with:
+
+```bash
+[my-first-app] $ rpm:packageBin
+```
+
+> There will be some error logging. This is because rpm logs to stderr instead of stdout.
+
+### Including additional files in your distribution
+
+Anything included in your project's `dist` directory will be included in the distribution built by the native packager. Note that in Play, the `dist` directory is equivalent to the `src/universal` directory mentioned in the native packager's own documentation.
+
+## Play PID Configuration
+
+Play manages its own PID, which is described in the [[Production configuration|ProductionConfiguration]].
+
+Since Play uses a separate pidfile, we have to provide it with a proper path, which is `packageName.value` here. The name of the pid file must be `play.pid`. In order to tell the startup script where to place the PID file, put a file `application.ini` inside the `dist/conf` folder and add the following content:
+
+```bash
+s"-Dpidfile.path=/var/run/${packageName.value}/play.pid",
+# Add all other startup settings here, too
+```
+
+Please see the sbt-native-packager [page on Play](https://sbt-native-packager.readthedocs.io/en/v1.3.25/recipes/play.html) for more details.
+
+To prevent Play from creating a PID just set the property to `/dev/null`:
+
+```bash
+-Dpidfile.path=/dev/null
+```
+
+For a full list of replacements take a closer look at the [customize java server documentation](https://sbt-native-packager.readthedocs.io/en/v1.3.25/archetypes/java_server/customize.html) and [customize java app documentation](https://sbt-native-packager.readthedocs.io/en/v1.3.25/archetypes/java_app/customize.html).
+
+## Publishing to a Maven (or Ivy) repository
+
+You can also publish your application to a Maven repository. This publishes both the JAR file containing your application and the corresponding POM file.
+
+You have to configure the repository you want to publish to, in your `build.sbt` file:
+
+@[publish-repo](code/production.sbt)
+
+Then in the Play console, use the `publish` task:
+
+```bash
+[my-first-app] $ publish
+```
+
+> Check the [sbt documentation](https://www.scala-sbt.org/release/docs/index.html) to get more information about the resolvers and credentials definition.
+
+## Running a production server in place
+
+In some circumstances, you may not want to create a full distribution, you may in fact want to run your application from your project's source directory. This requires an sbt installation on the server, and can be done using the `stage` task.
+
+```bash
+$ sbt clean stage
+```
+
+And you will see something like this:
+
+```bash
+$ sbt
+[info] Loading global plugins from /Users/play-developer/.sbt/0.13/plugins
+[info] Loading project definition from /Users/play-developer/my-first-app/project
+[info] Set current project to my-first-app (in build file:/Users/play-developer/my-first-app/)
+[my-first-app] $ stage
+[info] Updating {file:/Users/play-developer/my-first-app/}root...
+[info] Packaging /Users/play-developer/my-first-app/target/scala-2.11/my-first-app_2.11-1.0-SNAPSHOT-sources.jar ...
+[info] Done packaging.
+[info] Wrote /Users/play-developer/my-first-app/target/scala-2.11/my-first-app_2.11-1.0-SNAPSHOT.pom
+[info] Resolving jline#jline;2.12.2 ...
+[info] Done updating.
+[info] Main Scala API documentation to /Users/play-developer/my-first-app/target/scala-2.11/api...
+[info] Compiling 8 Scala sources and 1 Java source to /Users/play-developer/my-first-app/target/scala-2.11/classes...
+[info] Packaging /Users/play-developer/my-first-app/target/scala-2.11/my-first-app_2.11-1.0-SNAPSHOT-web-assets.jar ...
+[info] Done packaging.
+model contains 21 documentable templates
+[info] Main Scala API documentation successful.
+[info] Packaging /Users/play-developer/my-first-app/target/scala-2.11/my-first-app_2.11-1.0-SNAPSHOT-javadoc.jar ...
+[info] Done packaging.
+[info] Packaging /Users/play-developer/my-first-app/target/scala-2.11/my-first-app_2.11-1.0-SNAPSHOT.jar ...
+[info] Done packaging.
+[info] Packaging /Users/play-developer/my-first-app/target/scala-2.11/my-first-app_2.11-1.0-SNAPSHOT-sans-externalized.jar ...
+[info] Done packaging.
+[success] Total time: 8 s, completed Feb 6, 2017 2:11:10 PM
+[my-first-app] $
+```
+
+This cleans and compiles your application, retrieves the required dependencies and copies them to the `target/universal/stage` directory. It also creates a `bin/` script where `` is the project's name. The script runs the Play server on Unix style systems and there is also a corresponding `bat` file for Windows.
+
+For example to start an application of the project `my-first-app` from the project folder you can:
+
+```bash
+$ target/universal/stage/bin/my-first-app -Dplay.http.secret.key=abcdefghijk
+```
+
+You can also specify a different configuration file for a production environment, from the command line:
+
+```bash
+$ target/universal/stage/bin/my-first-app -Dconfig.file=/full/path/to/conf/application-prod.conf
+```
+
+### Running a test instance
+
+Play provides a convenient utility for running a test application in prod mode.
+
+> **Note:** This is not intended for production usage.
+
+To run an application in prod mode, run `runProd`:
+
+```bash
+[my-first-app] $ runProd
+```
+
+## Using the sbt assembly plugin
+
+Though not officially supported, the sbt assembly plugin may be used to package and run Play applications. This will produce one jar as an output artifact, and allow you to execute it directly using the `java` command.
+
+To use this, add a dependency on the plugin to your `project/plugins.sbt` file:
+
+```scala
+addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5")
+```
+
+Now add the following configuration to your `build.sbt`:
+
+@[assembly](code/assembly.sbt)
+
+Now you can build the artifact by running `sbt assembly`, and run your application by running:
+
+```
+$ java -Dplay.http.secret.key=abcdefghijk -jar target/scala-2.XX/