Documentation

You are viewing the documentation for the 2.5.0-M2 development release. The latest stable release series is 3.0.x.

§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.

§Scala 2.10 support discontinued

While Play 2.4 was cross compiled against both Scala 2.10 and Scala 2.11, this new release of Play is only available for Scala 2.11. The reason for dropping Scala 2.10 support is that Play has a new library dependency on scala-java8-compat, which is only available for Scala 2.11. This library makes it easy to convert from and to common Scala and Java8 types, and hence it’s valuable to simplify the Play core. Furthermore, you may also find it handy to use in your own Play project. For example, if you need to convert Scala Future instances into Java CompletionStage (or the other way around).

§Replaced functional types with Java8 functional types

All functional types have been replaced with their Java8 counterparts:

Besides the name change, the main difference is in the methods’ signature. In fact, while the method in the Play types could throw an exception, the Java8 types don’t. The consequence is that you will now have to catch exceptions in the lambda’s body if it can throw a checked exception. Practically, this is easy to fix. Let’s suppose you used to pass a F.Callback0 instance to an onClose method:

onClose(() -> {
    database.stop(); // <-- suppose this can throw an IOException
})

And further assume that the onClose method was changed and it now takes a java.lang.Runnable argument, instead of F.Callback0. Because Runnable cannot throw a checked exception, you must change your implementation using something like this:

onClose(() -> {
    try {
        database.stop(); // <-- suppose this can throw an IOException
    }
    catch(IOException e) {
        throw new RuntimeException(e);
    }
})

To avoid copy-pasting a repetitive try-catch construct all across your project, you might consider adopting the Durian library’s Errors class (either through Maven or by copy-pasting two classes). It allows you to easily wrap lambdas which throw checked exceptions as their standard Java 8 functional interface, as such:

onClose(Errors.rethrow().wrap(database::stop));
onClose(Errors.log().wrap(database::stop));
// You can also make your own error handler, see https://github.com/diffplug/durian/blob/master/test/com/diffplug/common/base/ErrorsExample.java?ts=4

If you are using the java8 lambda syntax and the lambda’s body does not throw a checked exception, then you won’t need to change anything in your code.

Last but not least, if you are using F.Callback3<A,B,C> in your application, since there is no Java8 replacement for it, you may want to use akka.japi.function.Function3.

§Replaced F.Option with Java8 Optional

F.Option has been discontinued and we embraced the Java8 Optional type. 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 inherited from java.util.Collection, Optional doesn’t.

Here follows a short table that should ease the migration:

F.Option Optional
None empty
Some ofNullable
isDefined isPresent
isEmpty !isPresent
get get
getOrElse ifPresent
map map

Optional has a lot more combinators, so we highly encourage you to discover its API if you are not familiar with it already.

§Replaced static methods with dependency injection

If you are using controllers.ExternalAssets in your routes file you must either set routesGenerator := InjectedRoutesGenerator in your build.sbt or you must use the @ symbol in front of the route like GET /some/path @controllers.ExternalAssets.at

§Removed Plugins API

Play’s Plugin API was deprecated in 2.4, and has been removed.

To create reusable components that are dependency injection independent, please use Play’s module system play.api.inject.Module. Otherwise, a singleton bound to a dependency injected module (either Scala or Java) is usually enough to replace the Plugin API completely.

As part of this effort, the modules directory has been refactored to only include up to date modules that do not use the Plugin API.

§Refactored Logback as an optional dependency

The runtime dependency on Logback has been removed, and Play can now use any SLF4J compatible logging framework. Logback is included by default, but because it exists as a separate module outside of Play (and is not part of the Logger class), the play.api.Logger$ColoredLevel converter in logback.xml has changed to play.api.libs.logback.ColoredLevel:

<conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel" />

Details on how to set up Play with different logging frameworks are in Configuring logging section.

§Renamed Ning components into Ahc

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*.

Next: Play 2.4 migration guide