Skip to content

kryo-5.7.0

Latest

Choose a tag to compare

@theigl theigl released this 01 Oct 14:05
· 16 commits to master since this release

This is a feature release that hardens deserialization against corrupt or malicious input, adds long-requested serializers for unmodifiable and synchronized JDK collections, and fixes several bugs. It also improves compatibility with recent JDKs up to Java 26.

Highlights

Safer deserialization of untrusted or corrupt data (#1284)

Before this release, a tiny corrupt payload that declared a huge array, string, collection or map size could make Kryo allocate gigabytes of memory and fail with an OutOfMemoryError. Kryo now checks declared sizes against the bytes left in the buffer before it allocates anything, and rejects impossible array and string sizes with a KryoException. Collection and map capacities are capped at the bytes remaining. When reading from an InputStream, where the total size isn't known in advance, you can cap declared sizes with the new Input.setMaxArraySize(int):

input.setMaxArraySize(1024 * 1024); // reject any declared array/string/collection/map size above 1M elements

Serializers for unmodifiable and synchronized collections (#1154)

Kryo now includes serializers for the JDK's Collections.unmodifiable* and Collections.synchronized* wrappers. This has been one of the most requested features. Because they read private JDK fields through sun.misc.Unsafe, they are not registered by default and must be enabled explicitly:

UnmodifiableCollectionSerializers.addDefaultSerializers(kryo);
SynchronizedCollectionSerializers.addDefaultSerializers(kryo);
// or, when registration is required:
UnmodifiableCollectionSerializers.registerSerializers(kryo);
SynchronizedCollectionSerializers.registerSerializers(kryo);

See the README for details.

All changes

  • #1154 Add serializers for unmodifiable and synchronized collections
  • #1179 Add better feedback when using abstract classes in serialization (thanks @pvlov)
  • #1183 Add ConcurrentHashMap.KeySetView serializer (thanks @bergander)
  • #1253 Make @Optional annotation repeatable (thanks @www84)
  • #1271 Use constants for array base offsets instead of Unsafe.arrayBaseOffset to avoid warnings on JDK 25+
  • #1283 Fix generics stack leak that poisoned reused Kryo instances (thanks @Icesource)
  • #1284 Guard deserialization against unbounded allocation from declared sizes (thanks @joszamama)
  • #1300 Cache the Java serializer lookup per type in ExternalizableSerializer (thanks @vpaturet)
  • #1309 Preserve circular references in externalizable objects (thanks @Ishubhammohole)
  • Revert wrapping of OutOfMemoryError in KryoException in FieldSerializer (#829)
  • Log a warning when @BindCollection or @BindMap sets a serializer without the element, key, or value class, and improve the error when a serializer factory in @Bind, @BindCollection, or @BindMap needs the missing class
  • Fix the error message for duplicate tags in TaggedFieldSerializer, which could throw an IndexOutOfBoundsException instead
  • Upgrade Objenesis from 3.4 to 3.6

Other Tasks:

  • Test CI build against Java 23, 24, 25 and 26
  • Switch release publishing to the Central Portal (#1188)
  • Ensure main sources are always compiled for Java 8, regardless of the JDK used for the build
  • Fix nondeterministic tests (#1219, #1220, #1227) (thanks @yonghanlin, @annhchen89)
  • Documentation updates (#1245) (thanks @fzhyzamt)
  • Upgrade Maven plugins and test dependencies

The full list of changes can be found here.

Many thanks to all contributors!

Upgrade Notes

For migration from previous major versions please check out the migration guide. We're asking the community to help and contribute this part: please edit the migration wiki page as you encounter any information or issues that might help others.

Behavioral changes

  • Malformed input that declares array or string sizes larger than the remaining data now fails fast with a KryoException instead of trying to allocate memory. Collection and map capacities are capped instead (#1284).
  • FieldSerializer no longer wraps OutOfMemoryError in a KryoException. Errors are now passed through unchanged.
  • Kryo.reset() now also clears the generics stacks, so an exception during (de)serialization no longer leaves pooled or thread-local Kryo instances in a broken state (#1283).

Compatibility

  • Serialization compatible
    • Standard IO: Yes
    • Unsafe-based IO: Yes
  • Binary compatible - Yes (Details)
  • Source compatible - Yes (Details)