Skip to content

Fail to serialize/deserialize immutable collections #689

Closed

Description

@MrTetrixx

We have run into an issue in 5.0.0-RC4.0.0 where we serialize an immutable list and see this exception when deserializing:

Caused by: java.lang.UnsupportedOperationException: null
        at java.base/java.util.Collections$UnmodifiableCollection.add(Collections.java:1058)
        at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:235)
        at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:43)
        at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:718)
        at com.esotericsoftware.kryo.serializers.ReflectField.read(ReflectField.java:114)
        ... 23 common frames omitted

and also

com.esotericsoftware.kryo.KryoException: Class cannot be created (missing no-arg constructor): java.util.Collections$UnmodifiableRandomAccessList

	at com.esotericsoftware.kryo.util.DefaultInstantiatorStrategy.newInstantiatorOf(DefaultInstantiatorStrategy.java:111)
	at com.esotericsoftware.kryo.Kryo.newInstantiator(Kryo.java:1105)
	at com.esotericsoftware.kryo.Kryo.newInstance(Kryo.java:1114)
	at com.esotericsoftware.kryo.serializers.CollectionSerializer.create(CollectionSerializer.java:172)
	at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:210)
	at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:43)
	at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:799)

Here is a test to replicate one of the scenarios:

 @Test(expected = KryoException.class)
    public void shouldNotExplodeWhenSerializeDeserializeImmutableCollection() {
        List<String> before = List.of("one", "two");

        Kryo kryo = new Kryo();
        kryo.setRegistrationRequired(false);
        Output output = new Output(4096, 4096);
        kryo.writeClassAndObject(output, before);
        output.close();

        kryo.readClassAndObject(new Input(output.toBytes()));
    }

Activity

  1. isaki commented on Aug 28, 2019

    @isaki
    Contributor

    You need to write your own serializer for Collections.unmodifiable*. There is no built in Kryo support for this.

  2. MrTetrixx commented on Aug 30, 2019

    @MrTetrixx
    Author

    Ok, thanks!
    Note that Collections.unmodifiable* has been in java since java 5 and Immutable is used more and more since it was introduced in java 9. Might be worth adding as a default feature in Kryo.

  3. isaki commented on Aug 30, 2019

    @isaki
    Contributor

    The difficulty is that unmodifiable* are decorators. I've written my own using a bit of reflection, but I understand the risk involved and I have very targeted use cases. Also, these are not actually immutable; they just provide views that can't be modified. The owner of the decorated collection can still modify it. For true immutability, I use Guava's Immutable collections. There is also Kryo support via an add-on library for these:

    https://github.com/magro/kryo-serializers

    EDIT: That package has support for unmodifiable*.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions