I have a class with a field of scala.collection.mutable.LongMap
type.
After serializing it with Kryo
I attempt to deserialize the object and get the following exception:
com.esotericsoftware.kryo.KryoException: java.lang.IllegalArgumentException: Can not set final scala.collection.mutable.LongMap field com.name.of.field to scala.collection.mutable.HashMap
Serialization trace:
field (com.name.of)
at com.esotericsoftware.kryo.serializers.FieldSerializer$ObjectField.read(FieldSerializer.java:626) ~[com.esotericsoftware.kryo.kryo-2.21.jar:na]
at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:221) ~[com.esotericsoftware.kryo.kryo-2.21.jar:na]
at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:648) ~[com.esotericsoftware.kryo.kryo-2.21.jar:na]
at com.esotericsoftware.kryo.serializers.FieldSerializer$ObjectField.read(FieldSerializer.java:605) ~[com.esotericsoftware.kryo.kryo-2.21.jar:na]
at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:221) ~[com.esotericsoftware.kryo.kryo-2.21.jar:na]
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:729) ~[com.esotericsoftware.kryo.kryo-2.21.jar:na]
IIUC the LongMap
is serialized as HashMap
and then deserialization fails as the HashMap
can't be written to the LongMap
field.
I manually ran something like https://github.com/romix/akka-kryo-serialization/blob/master/src/test/scala/com/romix/scala/serialization/kryo/MapSerializerTest.scala#L78 and confirmed that serialized LongMap
is deserialized into a HashMap
.
Any idea how to properly read/write this Object so the LongMap
will be read as LongMap
instead of HashMap
?
Do I need to use a proxy class? write a custom serializer/deserializer?
Alternatively, is there a decent serialization library that handles LongMap
s properly?
P.S. I would have tagged the question with LongMap
but I don't have enough reputation to create new tags.
Yes, you need to add a custom serializer. There is https://github.com/twitter/chill#serializers-for-scala-classes which includes serializers for some types in Scala standard library, but apparently not for LongMap
(you may already be using this library, perhaps indirectly). Look at how they do it and write your own.
However, this error shouldn't happen by default. Look for Kryo#register
and Kryo#setDefaultSerializer
calls in your code (or code you call): are you telling Kryo to serialize/deserialize all scala.collection.mutable.Map
s as HashMap
s?