Class KryoSerializer

java.lang.Object
com.loomcache.common.serialization.KryoSerializer
All Implemented Interfaces:
LoomSerializer

public final class KryoSerializer extends Object implements LoomSerializer
Thread-safe Kryo serializer using a Kryo Pool.

Why Kryo? - 2-10x faster than Java Serializable - 30-40% smaller payloads with pre-registered classes - No reflection overhead when classes are registered - Supports Java 25 records

Thread safety: Kryo instances are NOT thread-safe. We use a Pool (backed by SoftReferences) so instances are reused under memory pressure and GC'd when not needed. This is superior to ThreadLocal for virtual threads (millions of vthreads would create millions of Kryo instances with ThreadLocal).

  • Constructor Summary

    Constructors
    Constructor
    Description
    Create a new KryoSerializer with a pooled Kryo instance pool.
  • Method Summary

    Modifier and Type
    Method
    Description
    <T> @Nullable T
    deserialize(byte @Nullable [] bytes)
    Deserialize a byte array to an object (type encoded in bytes).
    <T> @Nullable T
    deserialize(byte @Nullable [] bytes, Class<T> type)
    Deserialize a byte array to a known type (faster — no class header).
    @Nullable Object
    deserializeForSnapshot(byte @Nullable [] bytes)
    Deserialize a snapshot payload using the larger snapshot-specific size cap.
    boolean
    Returns whether the exact class was explicitly registered by application code through registerClass(Class, int).
     
    void
    registerClass(Class<?> clazz, int id)
    Register additional application-specific classes.
    <T> void
    registerClass(Class<T> clazz, int id, com.esotericsoftware.kryo.Serializer<? super T> serializer)
    Register an application-specific class with an explicit Kryo serializer.
    <T> byte[]
    serialize(@Nullable T obj, Class<T> type)
    Serialize a known-type object (slightly faster — skips class header).
    byte[]
    serialize(@Nullable Object obj)
    Serialize an object to a byte array.
    byte[]
    serialize(@Nullable Object obj, int maxBytes)
    Serialize an object to a byte array with a caller-provided byte ceiling.
    byte[]
    Serialize a snapshot payload without the bounded 1 MiB protocol buffer cap.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • KryoSerializer

      public KryoSerializer()
      Create a new KryoSerializer with a pooled Kryo instance pool.
  • Method Details

    • name

      public String name()
      Specified by:
      name in interface LoomSerializer
    • registerClass

      public void registerClass(Class<?> clazz, int id)
      Register additional application-specific classes. Call this at startup to register your @Entity and domain objects.

      Clears existing pooled Kryo instances so that subsequent borrows create fresh instances with the new registration applied.

      Parameters:
      clazz - the class to register (must not be null)
      id - the registration ID (must be unique and >= 20)
    • registerClass

      public <T> void registerClass(Class<T> clazz, int id, com.esotericsoftware.kryo.Serializer<? super T> serializer)
      Register an application-specific class with an explicit Kryo serializer.

      Serialization resolution is now ordered: null sentinel, application class-specific serializer, application class registration, base Kryo registrations, then fail-closed for unknown classes. The same class, ID, and serializer must be configured consistently on every node that may exchange the payload.

      Type Parameters:
      T - the registered type
      Parameters:
      clazz - the class to register (must not be null)
      id - the registration ID (must be unique and not reserved)
      serializer - the class-specific serializer to use before Kryo's default serializer
    • isApplicationRegisteredClass

      public boolean isApplicationRegisteredClass(Class<?> clazz)
      Returns whether the exact class was explicitly registered by application code through registerClass(Class, int).

      Base protocol/JDK registrations are intentionally excluded. Callers use this as a narrow security boundary for payloads, such as executor tasks, that must be opted in by deployment code before deserialization results are trusted for execution.

      Parameters:
      clazz - the runtime class to check
      Returns:
      true when the exact class was application-registered
    • serialize

      public byte[] serialize(@Nullable Object obj)
      Serialize an object to a byte array.
      Specified by:
      serialize in interface LoomSerializer
      Parameters:
      obj - the object to serialize (may be null)
      Returns:
      the serialized bytes, or empty array if obj is null
    • serialize

      public byte[] serialize(@Nullable Object obj, int maxBytes)
      Serialize an object to a byte array with a caller-provided byte ceiling.
      Parameters:
      obj - the object to serialize (may be null)
      maxBytes - maximum serialized payload size in bytes
      Returns:
      the serialized bytes, or empty array if obj is null
    • serialize

      public <T> byte[] serialize(@Nullable T obj, Class<T> type)
      Serialize a known-type object (slightly faster — skips class header).
      Specified by:
      serialize in interface LoomSerializer
      Type Parameters:
      T - the type parameter
      Parameters:
      obj - the object to serialize (may be null)
      type - the type of the object (must not be null)
      Returns:
      the serialized bytes, or empty array if obj is null
    • serializeForSnapshot

      public byte[] serializeForSnapshot(@Nullable Object obj)
      Serialize a snapshot payload without the bounded 1 MiB protocol buffer cap.
      Specified by:
      serializeForSnapshot in interface LoomSerializer
      Parameters:
      obj - the object to serialize (may be null)
      Returns:
      the serialized bytes, or empty array if obj is null
    • deserializeForSnapshot

      public @Nullable Object deserializeForSnapshot(byte @Nullable [] bytes)
      Deserialize a snapshot payload using the larger snapshot-specific size cap.
      Specified by:
      deserializeForSnapshot in interface LoomSerializer
      Parameters:
      bytes - the serialized snapshot bytes (may be null or empty)
      Returns:
      the deserialized object, or null if bytes are null/empty
    • deserialize

      public <T> @Nullable T deserialize(byte @Nullable [] bytes)
      Deserialize a byte array to an object (type encoded in bytes).
      Specified by:
      deserialize in interface LoomSerializer
      Type Parameters:
      T - the type parameter
      Parameters:
      bytes - the serialized bytes (may be null or empty)
      Returns:
      the deserialized object, or null if bytes are null/empty
    • deserialize

      public <T> @Nullable T deserialize(byte @Nullable [] bytes, Class<T> type)
      Deserialize a byte array to a known type (faster — no class header).
      Specified by:
      deserialize in interface LoomSerializer
      Type Parameters:
      T - the type parameter
      Parameters:
      bytes - the serialized bytes (may be null or empty)
      type - the target type (must not be null)
      Returns:
      the deserialized object, or null if bytes are null/empty