Lagom 1.6 Migration Guide

§Lagom 1.6 Migration Guide

This guide explains how to migrate from Lagom 1.5 to Lagom 1.6. If you are upgrading from an earlier version, be sure to review previous migration guides.

Lagom 1.6 updates to the latest major versions of Play (2.8), Akka (2.6) and Akka HTTP (10.1). We have highlighted the changes that are relevant to most Lagom users, but you may need to change code in your services that uses Play APIs directly. You’ll also need to update any Play services in your Lagom project repositories to be compatible with Play 2.8. Please refer to the Play 2.8 migration guide, Akka Migration Guide 2.5.x to 2.6.x and the Akka HTTP 10.1.x release announcements for more details.

For a detailed list of version upgrades of other libraries Lagom builds on such as for Slick, Kafka and others, refer to the release notes.

§Migrating from Lagom 1.5

To migrate from Lagom 1.5 we recommend first migrating to latest version of Lagom 1.5 before upgrading to Lagom 1.6. Refer to the release notes for details upgrading to latest version of Lagom 1.5.

§Build changes

§Maven

If you’re using a lagom.version property in the properties section of your root pom.xml, then simply update that to 1.6.0. Otherwise, you’ll need to go through every place that a Lagom dependency, including plugins, is used, and set the version there.

Note: Lagom 1.6 requires, at least, Maven 3.6.0. Please update your environments.

§sbt

The version of Lagom can be updated by editing the project/plugins.sbt file, and updating the version of the Lagom sbt plugin. For example:

addSbtPlugin("com.lightbend.lagom" % "lagom-sbt-plugin" % "1.6.0")

Lagom 1.6 requires sbt 1.3.2 or later, upgrade your version by updating the sbt.version in project/build.properties.

§Main changes

§Jackson serialization

Lagom is now using the Jackson serializer from Akka, which is an improved version of the serializer in Lagom 1.5. You can find more information about the Akka Jackson serializer in the Akka documentation. It is compatible with Lagom 1.5 in both directions.

The serializer provided by Akka creates new Akka serialization bindings so if you want to do a rolling upgrade from Lagom 1.5.x to Lagom 1.6.x you need to do a multi-step upgrade.

§JacksonJsonMigration

If you have used JacksonJsonMigration classes they must be changed to extend akka.serialization.jackson.JacksonMigration instead. It has the same method signatures as the deprecated JacksonJsonMigration.

The configuration in lagom.serialization.json.migrations must be moved to akka.serialization.jackson.migrations.
It has the same structure.

§Service API

The default settings for the ObjectMapper that is used for JSON serialization in the Service API now uses ISO-8601 date formats. The default in previous versions of Lagom was to use Jackson private format which can be more time and/or space efficient. The reason for this change is that the ISO format is a better default for interoperability.

If you want your Service API to produce the same output for types like java.time.Instantor java.time.LocalDateTime adjust the configuration for the ObjectMapper in your application.conf:

akka.serialization.jackson {
  # Configuration of the ObjectMapper for external service api
  jackson-json-serviceapi {
     # Serializes dates using Jackson custom formats
     WRITE_DATES_AS_TIMESTAMPS = on
  }
}

§Configuration changes

  • lagom.serialization.json.compress-larger-than is now configured with akka.serialization.jackson.jackson-json-compressed.compression.compress-larger-than
  • lagom.serialization.json.jackson-modules is now configured in akka.serialization.jackson.jackson-modules

§JSON Compression threshold

When marking a serializable class with CompressedJsonable compression will only kick in when the serialized representation goes past a threshold. The default value for akka.serialization.jackson.jackson-json-compressed.compression.compress-larger-than is 32 Kilobytes. As mentioned above, this setting was previously configure by lagom.serialization.json.compress-larger-than and defaulted to 1024 bytes. (See #1983)

§Remoting Artery

Lagom 1.6.0 builds on Akka 2.6.0 that uses a new Akka Remote implementation called Artery. Artery is enabled by default in Lagom and replaces the previous Akka Remote protocol (aka. Akka Remote Classic). If you are using Lagom in a clustered setup, you will need to shutdown all nodes before updating, unless you choose to disable Artery.

To use classic remoting instead of Artery, you need to:

  1. Set property akka.remote.artery.enabled to false. Further, any configuration under akka.remote that is specific to classic remoting needs to be moved to akka.remote.classic. To see which configuration options are specific to classic search for them in: akka-remote/reference.conf
  2. Add Netty dependency as explained in Akka Remoting docs:
libraryDependencies += "io.netty" % "netty" % "3.10.6.Final"

§Shard Coordination

In Lagom 1.4 and 1.5 users could use the akka.cluster.sharding.store-state-mode configuration key to switch from the default persistence-based shard coordination to the ddata-based coordination. As of Lagom 1.6 ddata is the new default.

Switching from persistence to ddata, such as if your cluster relies of Lagom’s default configuration, will require a full cluster shutdown. Therefore, if you want to avoid the full service shutdown when migrating to Lagom 1.6 you need to explicitly opt-back to persistence, as such:

# Opt-back to Lagom 1.5's 'persistence' instead of Lagom 1.6's default of 'ddata'.
akka.cluster.sharding.state-store-mode = persistence

§Akka Persistence Cassandra Update

The Akka Persistence Cassandra plugin is updated to version 0.101. This version requires two schema migrations before you upgrade to Lagom 1.6.0. For more information on how to migrate, consult the following documentations:

Note that although it’s technically possible to run the migrations while running your application we advise against it.

§Upgrading a production system

As usual, before upgrading to Lagom 1.6.0, make sure you are using the latest version on the 1.5.x series.

During a rolling upgrade your Projections may experience a degraded behavior. The service will self-heal when the rolling upgrade completes. Some internal messages taking care of the distribution of the worker instances of your projection have changed. As a consequence, your old nodes won’t be able to gossip with the new ones but as soon as the rolling upgrade completes, all nodes will be on the same version of your service the projection will operate normally.

§Split Brain Resolver

If you are subscriber of the Lightbend Platform and use the Akka Split Brain Resolver, when you update to Lagom 1.6.4 you can opt out of the commercial implementation and use the Open Source Akka Split Brain Resolver. The migration has two steps:

  1. remove the dependency:
// before
"com.lightbend.akka" %% "akka-split-brain-resolver" % "1.1.14"
// after
// The OSS SBR implementation is part of "akka-cluster" so you don't need to add a new dependency
  1. update your settings to use the new implementation:
## Before:
akka.cluster.downing-provider-class = "com.lightbend.akka.sbr.SplitBrainResolverProvider"
## After:
akka.cluster.downing-provider-class = "akka.cluster.sbr.SplitBrainResolverProvider"

Note that a rolling upgrade where some nodes use the commercial SBR and other nodes use the OSS SBR is possible as long as all nodes use the same configuration values (active-strategy, stable-after,…)

§Cluster shutdown migrating from Lagom 1.5

Lagom 1.6.0 has a few new default settings that will prevent you to run a rolling upgrade. In case you prefer to run a rolling upgrade, you will need to opt-out from each of these new defaults as explained below.

This is a summary of changes in Lagom 1.6 that would require a full cluster shutdown rather than a rolling upgrade:

§A note on Rolling Updates and PATCH Versions

Sometimes patch versions of Akka Cluster introduce changes that make certain pairs of versions incompatible. As a consequence, sometimes it is necessary to upgrade in multiple steps if downtime is not possible. See, for example, the following note in the Akka Docs on Rolling Updates and Versions:

This means that a rolling update will have to go through at least one of 2.6.2, 2.6.3 or 2.6.4 when upgrading to 2.6.5 or higher or else cluster nodes will not be able to communicate during the rolling update.

What this means for Lagom is that directly upgrading from 1.6.0 to 1.6.3, for example, is not possible in a rolling upgrade. Instead, you should first migrate to 1.6.2 deploy the upgraded version and then upgrade to 1.6.3. Following is a table of safe migrations (versions that can coexist safely during a rolling upgrade):

from to
1.6.0 1.6.2
1.6.1 1.6.3
1.6.2 1.6.3

Note: Lagom doesn’t use jackson-cbor serializer internally, but if you have jackson-cbor in your serialization-bindings you need to know about JacksonCborSerializer issue in Akka, and a rolling upgrade will have to go through 1.6.3 when upgrading to 1.6.3 or higher.

§Multi-step upgrade: serialization

Changes in default serializers require rolling upgrades to happen in two steps.

§Step 1: new binary, old serializers

First, you will have to deploy a version of your binary that’s already a Lagom 1.6.x application but you must set it up to use the serializers that are compatible with Lagom 1.5.x so your old nodes can continue to operate. On your application.conf use:

## Lagom 1.6 no longer enables Java serialization by default but some
## code in Lagom 1.5 (or your own code) still used it so we enable it back.
akka.actor.allow-java-serialization = on

## Configures Akka to only produce messages using the `old-lagom-json` serializer
akka.actor {
  serialization-bindings {
    "com.lightbend.lagom.serialization.Jsonable" = old-lagom-json
    "com.lightbend.lagom.serialization.CompressedJsonable" = old-lagom-json
  }
}

The setup above makes all traffic and durable data produced by Lagom 1.6 code to be readable by a Lagom 1.5 binary.

§Step 2: new binary, default serializers

Once all your production nodes are running a binary of your service based on Lagom 1.6 you can remove the settings for the old serializers from application.conf and use the defaults.

Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.