使用Kryo反序列化序列化对象(从文件)时,我得到以下异常:
java.lang.ExceptionInInitializerError
(...)
Caused by: com.esotericsoftware.kryo.KryoException: (...)
Serialization trace: (...)
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125)
at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:528)
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:786)
at com.esotericsoftware.kryo.serializers.MapSerializer.read(MapSerializer.java:143)
at com.esotericsoftware.kryo.serializers.MapSerializer.read(MapSerializer.java:21)
at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:682)
(...)
Caused by: java.lang.IndexOutOfBoundsException: Index: 1582, Size: 2
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at com.esotericsoftware.kryo.util.MapReferenceResolver.getReadObject(MapReferenceResolver.java:42)
at com.esotericsoftware.kryo.Kryo.readReferenceOrNull(Kryo.java:830)
at com.esotericsoftware.kryo.Kryo.readObjectOrNull(Kryo.java:753)
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:113)
... 27 more
我的假设是反序列化(即它改变了)时序列化格式没有被正确理解。 用于序列化和反序列化的Kryo版本是相同的。在序列化时,java版本可能有所不同:这可能是一个解释吗?
如果没有,关于我生成此类异常的任何其他提示都非常受欢迎!
非常感谢,托马斯
建议更新:,特此是从文件中反序列化的类
反序列化的主要类是HashMap<Integer, PreflopEhsVO>
自定义类定义(子和父)是:
public class PreflopEhsVOExtended extends PreflopEhsVO{
private int numbValues = 0;
public synchronized void addValue(PreflopEhsVO values){
if (numbValues == 0) this.valuesPerNumbOpp = values.valuesPerNumbOpp;
else{
//Weighted avg
for (int i=0; i<this.valuesPerNumbOpp.length; ++i) this.valuesPerNumbOpp[i] = (this.valuesPerNumbOpp[i] * numbValues + values.valuesPerNumbOpp[i]) / (float) (numbValues + 1);
++numbValues;
}
}
public PreflopEhsVOExtended(PreflopEhsVO values) {
this.valuesPerNumbOpp = values.valuesPerNumbOpp;
this.numbValues = 1;
}
}
public class PreflopEhsVO {
public float[] valuesPerNumbOpp = new float[9];
public PreflopEhsVO(){
}
public PreflopEhsVO(float[] valuesPerNumbOpp) {
this.valuesPerNumbOpp = valuesPerNumbOpp;
}
}
答案 0 :(得分:5)
Kryo一般来说在不同的JVM中不稳定,除非您非常小心关于如何注册类型。
当Kryo遇到一个类型时,它还没有看到它增加一个计数器并将该类型注册到该值。它使用对象图中的这些值作为类型的别名(性能优化)。如果第二个JVM上的执行顺序略有不同(无论版本是否相同),那么Kryo将最终使用不同类型的别名注册表。这可以防止序列化的blob被反序列化。
解决这个问题的方法是打开&#34; strict&#34; kryo中的模式并使用显式ids手动注册类。
kryo.register(SomeClass.class, 1);
kryo.register(AnotherClass.class, 2);
这将确保类在两个JVM上都注册到相同的稳定ID。如果这样做,您应该能够获得稳定的跨JVM序列化。
另一个可能的问题可能是类序列化前后字段的更改。处理更改字段的唯一实用方法是使用TaggedFieldSerializer