documentation/manual/releases/release22/Migration22.md
This is a guide for migrating from Play 2.1 to Play 2.2. If you need to migrate from an earlier version of Play then you must first follow the [[Play 2.1 Migration Guide|Migration21]].
Play is now published under a different organization id. This is so that eventually we can deploy Play to Maven Central. The old organization id was play, the new one is com.typesafe.play.
The version also must be updated to 2.2.0.
In project/plugins.sbt, update the Play plugin to use the new organization id:
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.2.0")
In addition, if you have any other dependencies on Play artifacts, and you are not using the helpers to depend on them, you may have to update the organization and version numbers there.
project/build.properties is required to be updated to use sbt 0.13.0.
If you're using a multi-project build, and none of the projects has a root directory of the current directory, the root project is now determined by overriding rootProject instead of alphabetically:
override def rootProject = Some(myProject)
If you have set the scalaVersion (e.g. because you have a multi-project build that uses Project in addition to play.Project), you should update it to 2.10.2.
Play cache is now split out into its own module. If you are using the Play cache, you will need to add this as a dependency. For example, in Build.scala:
val addDependencies = Seq(
jdbc,
cache,
...
)
Note that if you depend on plugins that depend on versions of Play prior to 2.2 then there will be a conflict within caching due to multiple caches being loaded. Update to a later plugin version or ensure that older Play versions are excluded if you see this issue.
The sbt namespace was previously extended by Play e.g. sbt.PlayCommands.intellijCommandSettings. This is considered bad practice and so
Play now uses its own namespace for sbt related things e.g. play.PlayProject.intellijCommandSettings.
In order to simplify action composition and filtering, the Play results structure has been simplified. There is now only one type of result, SimpleResult, where before there were SimpleResult, ChunkedResult and AsyncResult, plus the interfaces Result and PlainResult. All except SimpleResult have been deprecated. Status, a subclass of SimpleResult, still exists as a convenience class for building results. In most cases, actions can still use the deprecated types, but they will get deprecation warnings. Actions doing composition and filters however will have to switch to using SimpleResult.
Previously, where you might have the following code:
def asyncAction = Action {
Async {
Future(someExpensiveComputation)
}
}
You can now use the Action.async builder:
def asyncAction = Action.async {
Future(someExpensiveComputation)
}
Previously the stream method on Status was used to produce chunked results. This has been deprecated, replaced with a chunked method, that makes it clear that the result is going to be chunked. For example:
def cometAction = Action {
Ok.chunked(Enumerator("a", "b", "c") &> Comet(callback = "parent.cometMessage"))
}
Advanced uses that created or used ChunkedResult directly should be replaced with code that manually sets/checks the TransferEncoding: chunked header, and uses the new Results.chunk and Results.dechunk enumeratees.
We are now recommending that action composition be done using ActionBuilder implementations for building actions.
Details on how to do these can be found [[here|ScalaActionsComposition]].
The iteratee produced by EssentialAction now produces SimpleResult instead of Result. This means filters that needed to work with the result no longer have to unwrap AsyncResult into a PlainResult, arguably making all filters much simpler and easier to write. Code that previously did the unwrapping can generally be replaced with a single iteratee map call.
Previously the constructor to SimpleResult took a Writeable for the type of the Enumerator passed to it. Now that enumerator must be an Array[Byte], and Writeable is only used for the Status convenience methods.
Previously Helpers.route() and similar methods returned a Result, which would always be an AsyncResult, and other methods on Helpers such as status, header and contentAsString took Result as a parameter. Now Future[SimpleResult] is returned by Helpers.route(), and accepted by the extraction methods. For many common use cases, where type inference is used to determine the types, no changes should be necessary to test code.
In order to simply action composition, the Java structure of results has been changed. AsyncResult has been deprecated, and SimpleResult has been introduced, to distinguish normal results from the AsyncResult type.
Previously, futures in async actions had to be wrapped in the async call. Now actions may return either Result or Promise<Result>. For example:
public static Promise<Result> myAsyncAction() {
Promise<Integer> promiseOfInt = Promise.promise(
new Function0<Integer>() {
public Integer apply() {
return intensiveComputation();
}
}
);
return promiseOfInt.map(
new Function<Integer, Result>() {
public Result apply(Integer i) {
return ok("Got result: " + i);
}
}
);
}
The signature of the call method in play.mvc.Action has changed to now return Promise<SimpleResult>. If nothing is done with the result, then typically the only change necessary will be to update the type signatures.
Iteratees, enumeratees and enumerators that execute application supplied code now require an implicit execution context. For example:
import play.api.libs.concurrent.Execution.Implicits._
Iteratee.foreach[String] { msg =>
println(msg)
}
The way that the F.Promise class executes user-supplied code has changed in Play 2.2.
In Play 2.1, the F.Promise class restricted how user code was executed. Promise operations for a given HTTP request would execute in the order that they were submitted, essentially running sequentially.
With Play 2.2, this restriction on ordering has been removed so that promise operations can execute concurrently. Work executed by the F.Promise class now uses [[Play's default thread pool|ThreadPools]] without placing any additional restrictions on execution.
However, for those who still want it, Play 2.1's legacy behavior has been captured in the OrderedExecutionContext class. The legacy behavior of Play 2.1 can be easily recreated by supplying an OrderedExecutionContext as an argument to any of F.Promise's methods.
The following code shows how to recreate Play 2.1's behaviour in Play 2.2. Note that this example uses the same settings as Play 2.1: a pool of 64 actors running within Play's default ActorSystem.
import play.core.j.OrderedExecutionContext;
import play.libs.Akka;
import play.libs.F.*;
import scala.concurrent.ExecutionContext;
ExecutionContext orderedExecutionContext = new OrderedExecutionContext(Akka.system(), 64);
Promise<Double> pi = Promise.promise(new Function0<Double>() {
Double apply() {
return Math.PI;
}
}, orderedExecutionContext);
Promise<Double> mappedPi = pi.map(new Function<Double, Double>() {
Double apply(x Double) {
return 2 * x;
}
}, orderedExecutionContext);
We have upgraded Jackson to version 2 which means that the package name is now com.fasterxml.jackson.core instead of org.codehaus.jackson.
The stage and dist tasks have been completely re-written in Play 2.2 so that they use the Native Packager Plugin.
Play distributions are no longer created in the project's dist folder. Instead, they are created in the project's target folder.
Another thing that has changed is the location of the Unix script that starts a Play application. Prior to 2.2 the Unix script was named start and it resided in the root level folder of the distribution. With 2.2 the start script is named as per the project's name and it resides in the distribution's bin folder. In addition there is now a .bat script available to start the Play application on Windows.
Please note that the format of the arguments passed to the
startscript has changed. Please issue a-hon thestartscript to see the arguments now accepted.
Please consult the [["Starting your application in production mode"|Production]] documentation for more information on the new stage and dist tasks.
The migration guide for upgrading from Akka 2.1 to 2.2 can be found here.