Serialization - hazelcast/hazelcast-scala GitHub Wiki

Built-in

The Scala API provides a set of default serializers for common data types. To enable, register them to the configuration:

serialization.Defaults.register(conf.getSerializationConfig)

Custom

The Hazelcast Java API provides two type-class interfaces for serialization, ByteArraySerializer and StreamSerializer. Both extend a common Serializer interface that requires a unique getTypeId().

In the Scala API this can be automated by encapsulating the serializers in an Enumeration container SerializerEnum, which removes the need for a separate place to track such ids.

Given an Employee class:

case class Employee(id: UUID, name: String)

The serializer implementation, inside the SerializerEnum container, would look like this:

import com.hazelcast.nio.{ObjectDataOutput, ObjectDataInput}
import java.util.UUID

object MySerializers extends SerializerEnum {
  val EmployeeSer = new StreamSerializer[Employee] {
    def write(out: ObjectDataOutput, emp: Employee): Unit = {
      out.writeLong(emp.uuid.getMostSignificantBits)
      out.writeLong(emp.uuid.getLeastSignificantBits)
      out.writeUTF(emp.name)
    }
    def read(inp: ObjectDataInput): Employee = {
      val id = new UUID(inp.readLong, inp.readLong)
      val name = inp.readUTF()
      Employee(id, name)
    }
  }
}

Like the default serializers, they must be registered:

MySerializers.register(conf.getSerializationConfig)

Serialization libraries

The SerializerEnum can also be leveraged to further minimize boilerplate, by using one of the many serialization libraries available.

E.g. to use the BooPickle library, you can easily write a general BooPickle container:

import java.nio.ByteBuffer
import scala.reflect.ClassTag
import com.hazelcast.Scala.serialization.SerializerEnum

import boopickle.Default._

class BooPicklers extends SerializerEnum {
  class BooPickle[T: Pickler: ClassTag] extends ByteArraySerializer[T] {
    def write(t: T): Array[Byte] = {
      val bb = Pickle.intoBytes(t)
      val bytes = new Array[Byte](bb.remaining)
      bb.get(bytes)
      bytes
    }
    def read(bytes: Array[Byte]): T = {
      val bb = ByteBuffer.wrap(bytes)
      Unpickle[T].fromBytes(bb)
    }
  }
}

With that, you can add your serializers without writing serialization code:

import boopickle.Default._

object MyPicklers extends BooPicklers {
  val EmployeeSer = new BooPickle[Employee]
}

Again, must be registered:

MyPicklers.register(conf.getSerializationConfig)