You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Fail to serialize/deserialize immutable collections #689
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()));
}
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.
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:
Activity
isaki commentedon Aug 28, 2019
You need to write your own serializer for Collections.unmodifiable*. There is no built in Kryo support for this.
MrTetrixx commentedon Aug 30, 2019
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.
isaki commentedon Aug 30, 2019
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*.