Skip to content
Filip Turczynowicz-Suszycki edited this page Dec 25, 2023 · 13 revisions

Kryo v5 brings many improvements that are incompatible with previous versions. This page highlights some of the most commonly encountered differences. If you come up with information that would be helpful to have here, please don't hesitate to help improve this page.

API changes

Serialization

Serializer read has changed. The old method:

T read (Kryo kryo, Input input, Class<T> type)

The new method:

T read (Kryo kryo, Input input, Class<? extends T> type)

Using the old method signature results in an ugly error:

Name clash: The method read(Kryo, Input, Class<T>) of type SomeSerializer has the same erasure as read(Kryo, Input, Class<? extends T>) of type Serializer<T> but does not override it

A thypical fix for this error is to change the method signature from:

public MyClass read(Kryo kryo, Input input, Class<MyClass> type)

to:

public MyClass read(Kryo kryo, Input input, Class<? extends MyClass> type)

Pooling

KryoPool has been replaced by the more generic class Pool.

See https://github.com/EsotericSoftware/kryo#pooling.

Configuration changes

  • Registration is now required by default (#398).
  • Reference tracking is now disabled by default (#617)

Migration guide

Any Kryo upgrade is a big event with a lot of potential for breakage. Moving from v2 to v5 or from v4 to v5 is about the same: the newer Kryo version is unlikely to be able to read bytes written with the older version. If going through the pain to update, moving to the latest makes the most sense. Also consider that if an older version is working fine, it may not be worth the pain to update.

The best approach is to load the old data, then write it with the newer version. For this purpose, Kryo 5 ships with a separate artifact that can be used alongside older versions. This is best because it is unreasonable to attempt to modify the old data to make it acceptable for the newer Kryo version.

The same can be done by moving the old data to an intermediary format. For example, load the data with Kryo v2 and write it to JSON. Update your application to Kryo v5, load the JSON data to objects, then write it with v5. The end result is the same as before, but without using classloaders and with the extra trouble of writing and reading the data to another format. Libraries like JsonBeans can do that automatically, at least for relatively simple object graphs.

If you allow your users to bring v2 data into your latest app which uses a new Kryo, you'll have to keep your classes compatible with the old v2 data. One way around this is to keep a snapshot of the old classes which your application no longer uses, then write code to convert old objects to your newer classes.

How to use Kryo 4 and Kryo 5 together

Step 1: Update dependencies in build.gradle

Option 1: Using Gradle

dependencies {
  api 'com.esotericsoftware:kryo:4.0.2'
  api 'com.esotericsoftware.kryo:kryo5:5.0.1'
}

Option 2: Using jars

Extract kryo-4.0.2.jar from https://github.com/EsotericSoftware/kryo/releases/tag/kryo-parent-4.0.2 and place to libs folder Extract kryo5-5.0.1.jar from https://github.com/EsotericSoftware/kryo/releases/tag/kryo-parent-5.0.1 and place to libs folder

dependencies {
  api "org.objenesis:objenesis:3.1"
  api "com.esotericsoftware:minlog:1.3.1"
  api "com.esotericsoftware:reflectasm:1.11.9"
  api files("libs/kryo-4.0.2.jar")
  api files("libs/kryo5-5.0.1.jar")
}

Step 2: Separate reading Kryo 4 data and reading/writing Kryo 5 data:

Use for Kryo 4 instances:

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;

Use for Kryo 5 instances:

import com.esotericsoftware.kryo.kryo5.Kryo;
import com.esotericsoftware.kryo.kryo5.io.Input;
import com.esotericsoftware.kryo.kryo5.io.Output;

General mnemonic on reading is the following:

if (kryo4Version)
  return kryo4.readObject(input4, ArrayList.class);
else
  return kryo5.readObject(input5, ArrayList.class);

For writing it makes sense to use Kryo 5 only:

kryo5.writeObject(output5, list);