2016-09-11 2 views
-1

У меня есть класс с полем scala.collection.mutable.LongMap.Deserializing LongMap in Kryo

После сериализации с Kryo Я пытаюсь десериализации объекта и получить следующее исключение:

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 LongMap сериализуется в HashMap, а затем десериализации терпит неудачу как HashMap не могут быть записаны в LongMap поле.

Я вручную запустил что-то вроде https://github.com/romix/akka-kryo-serialization/blob/master/src/test/scala/com/romix/scala/serialization/kryo/MapSerializerTest.scala#L78 и подтвердил, что сериализованный LongMap десериализуется в HashMap.

Любая идея, как правильно читать/записывать этот объект, так что LongMap будет считаться LongMap вместо HashMap?

Нужно ли использовать прокси-класс? написать собственный сериализатор/десериализатор? В качестве альтернативы, есть ли приличная библиотека сериализации, которая правильно обрабатывает LongMap?

P.S. Я бы пометил вопрос LongMap, но у меня недостаточно репутации для создания новых тегов.

+0

показать свое определение класса ... –

ответ

0

Да, вам нужно добавить собственный сериализатор. Существует https://github.com/twitter/chill#serializers-for-scala-classes, который включает сериализаторы для некоторых типов в стандартной библиотеке Scala, но, по-видимому, не для LongMap (возможно, вы уже используете эту библиотеку, возможно, косвенно). Посмотрите, как они это делают и напишите сами.

Однако эта ошибка не должна происходить по умолчанию. Ищите Kryo#register и Kryo#setDefaultSerializer звонки в ваш код (или код, который вы вызываете): вы говорите Kryo для сериализации/десериализации всех scala.collection.mutable.Map s как HashMap s?

+0

Спасибо, написав собственный сериализатор для LongMap, решил его. Я не называл явно 'Kryo # register' или' Kryo # setDefaultSerializer' и не инструктировал Kryo сериализовать/десериализовать 'Map' как 'HashMap'. Я предполагаю, что это поведение по умолчанию. – lalaland