Documentation

You are viewing the documentation for the 2.5.0-M1 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 in argument, instead of a F.Callback0. Here is how your implementation should be changed:

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

Wrapping the checked exception into a generic RuntimeException is not exactly considered a best practice. Therefore, you may want to create a specific exception type that is more appropriate to the abstraction. Having said that, if a lambda’s body does not throw a checked exception, and you are using the java8 lambda syntax as we did above, 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

Next: Play 2.4 migration guide