2015-11-21 31 views
6

Quando deserializzazione un oggetto serializzato (da un file) utilizzando Kryo, ottengo la seguente eccezione:La serializzazione Kryo dipende dalla versione Java?

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 

La mia ipotesi è che il formato serializzato non è capito correttamente quando la deserializzazione (vale a dire che ha cambiato.). La versione di Kryo per serializzare e deserializzare era la stessa. La versione di Java poteva essere diversa al momento della serializzazione: questa potrebbe essere una spiegazione?

In caso contrario, qualsiasi altro suggerimento su ciò che genera tali eccezioni è più che benvenuto!

Molte grazie, Thomas

UPDATE: come suggerito, con la presente la classe che viene deserializzato dal file

La classe principale deserializzati è HashMap<Integer, PreflopEhsVO> in cui le definizioni di classe personalizzati (figlio e padre) sono:

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

Difficile vedere come. Puoi pubblicare la lezione che è stata deserializzata? – EJP

+0

Certo - ho appena aggiornato il post – Tom

+0

Ho avuto gli stessi problemi con Kryo anche senza aggiornare la versione di Java. Siamo passati a FST: è estremamente stabile per Kryo –

risposta

5

Kryo in generale è non stabile tra diversi JVM a meno che non si sia molto prudente su come registrare i tipi.

Quando Kryo incontra un tipo che non ha visto prima incrementa un contatore e registra il tipo su quel valore. Utilizza questi valori nel grafico degli oggetti come alias per il tipo (ottimizzazione per le prestazioni). Se l'ordine di esecuzione è leggermente diverso sulla seconda JVM (indipendentemente dal fatto che la versione sia o meno la stessa), allora Kryo finirà con registri diversi di tipi con alias. Ciò impedisce che i BLOB serializzati vengano deserializzati.

La soluzione è attivare la modalità "strict" in kryo e registrare manualmente le classi con ID espliciti.

kryo.register(SomeClass.class, 1); 
    kryo.register(AnotherClass.class, 2); 

Questo farà sì che le classi vengono registrati per gli stessi ID stabili su entrambi i JVM. Se lo fai, dovresti essere in grado di ottenere una serializzazione JVM incrociata stabile.

Un altro possibile problema potrebbe essere una modifica nei campi della classe pre e post serializzazione. L'unico modo pratico per gestire i cambi di campo è con il TaggedFieldSerializer

Problemi correlati