Akka Serialization Helper
Serialization toolbox for Akka messages, events and persistent state that helps achieve compile-time guarantee on serializability.
To install the library use JitPack:
resolvers += "jitpack".at("https://jitpack.io") val commit = "master-SNAPSHOT" //name of a branch with -SNAPSHOT or raw commit hash
Then, add one or more of the modules below:
The project consists of three modules that are independent of each other, comprising a complete solution together.
1. Check For Base Trait
A Scala compiler plugin that detects messages, events and persistent state, and checks whether they extend the base trait and report an error when they don't. This ensures that the specified serializer is used by Akka and protects against accidental use of Java serialization.
To use, just annotate a base trait with
@SerializabilityTrait trait MySerializable
libraryDependencies += "com.github.VirtusLab.akka-serialization-helper" %% "serializability-checker-library" % commit libraryDependencies += compilerPlugin( "com.github.VirtusLab.akka-serialization-helper" %% "serializability-checker-compiler-plugin" % commit)
2. Dump Event Schema
An sbt plugin that allows for dumping schema of akka-persistence events to a file. Can be used for detecting accidental changes of events.
To dump events to
libraryDependencies += "com.github.VirtusLab.akka-serialization-helper" % "sbt-dump-event-schema" % commit
To enable the plugin for a specific project, use:
You also have to change one setting responsible for resolving companion compiler plugin:
dumpEventSchema / dumpEventSchemaCompilerPlugin := "com.github.VirtusLab.akka-serialization-helper" % "dump-event-schema-compiler-plugin" % commit
Circe-based Akka serializer. It uses codecs, derived using Magnolia, that are generated during compile time (so serializer won't crash during runtime like reflection-based serializers may do).
libraryDependencies += "com.github.VirtusLab.akka-serialization-helper" %% "circe-akka-serializer" % commit
Comparison of available Akka Serializers
|Data formats||JSON or CBOR||JSON||JSON or custom binary||JSON or custom binary||JSON or CBOR||custom binary|
|Scala support||very poor, even with jackson-module-scala:
||perfect out of the box||perfect with ScalaPB||perfect with Avro4s||perfect out of the box||perfect out of the box|
|Akka support||akka-serialization-jackson||requires custom serializer||used by akka-remote internally||requires custom serializer||requires custom serializer||akka-kryo|
|Compile-time mechanics||nothing happens in compile time; everything based on runtime reflection||derives codecs via Magnolia||with ScalaPB, generates Scala classes based on *.proto files||with Avro4s, derives Avro schemas using Magnolia||derives codecs without Magnolia||with akka-kryo, optionally derives codecs in compile time, but otherwise uses reflection in runtime|
|Runtime safety||none, uses reflection||encoders and decoders are created during compilation||*.proto files are validated before compilation||Avro schema is created during compilation||encoders and decoders are created during compilation||depends on whether codecs were derived in compile time (then standard for Scala code), or not (than none)|
||every top-level sealed trait must be registered manually||in case of custom types, a second layer of models is needed||sometimes requires annotations||every top-level sealed trait must be registered manually; every transitively included class must have an explicitly defined codec||every top-level sealed trait must be registered manually|