Java générique de sérialisation/désérialisation à l'aide de Kryo

Je suis en train de sérialiser et désérialiser des objets d'une classe personnalisée (par exemple, SomeClass, ayant une valeur par défaut aucun des arguments du constructeur) pour un byte[] tableau, à l'aide Kryo 2.19 et la valeur par défaut sérialiseur (FieldSerializer).

Sérialisation semble fonctionner OK, mais je reçois plusieurs exceptions dans la désérialisation, en fonction de la mise en œuvre effective de SomeClass.

Le code ressemble à ceci:

SomeClass object = getObject(); //Create and populate a new object of SomeClass

Kryo kryo = new Kryo();
FieldSerializer<?> serializer = new FieldSerializer<SomeClass>(kryo, SomeClass.class);
kryo.register(SomeClass.class, serializer);

ByteArrayOutputStream stream = new ByteArrayOutputStream();
Output output = new Output(stream);

kryo.writeObject(output, object);

output.close(); //Also calls output.flush()

byte[] buffer = stream.toByteArray(); //Serialization done, get bytes

//Deserialize the serialized object.
object = kryo.readObject(new Input(new ByteArrayInputStream(buffer)), SomeClass.class);

Un exemple des exceptions que je reçois est:

Exception in thread "main" java.lang.IncompatibleClassChangeError: Found interface org.objectweb.asm.MethodVisitor, but class was expected
    at com.esotericsoftware.reflectasm.ConstructorAccess.insertConstructor(ConstructorAccess.java:89)
    at com.esotericsoftware.reflectasm.ConstructorAccess.get(ConstructorAccess.java:70)
    at com.esotericsoftware.kryo.Kryo.newInstantiator(Kryo.java:1009)
    at com.esotericsoftware.kryo.Kryo.newInstance(Kryo.java:1059)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.create(FieldSerializer.java:228)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:217)
    at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:629)

Il semble que le type paramétré sont problématiques pour désérialiser. Pour tester cette hypothèse , ici, c'est paramétrée de la mise en œuvre de SomeClass et getObject():

class SomeClass<T extends Serializable>
{
    private final T[] elements;

    private final int first;
    private final int second;

    private SomeClass()
    {
        this.elements = null;
        this.first  = 0;
        this.second = 0;
    }

    private SomeClass(T[] elements, int first, int second)
    {
        this.elements = elements;
        this.first = first;
        this.second = second;
    }
}

SomeClass<?> getObject()
{
    String[] elements = new String[] {"This is a test", "one"};

    return new SomeClass<String>(elements, 1, 2);
}

Ce sérialise bien, mais la désérialisation jette l'exception suivante (observer la façon dont la première lettre de la chaîne n'est pas signalé à l'exception de cause):

Exception in thread "main" com.esotericsoftware.kryo.KryoException: Unable to find class: his is a test
Serialization trace:
elements (net.cetas.parserserver.data.report.SourceDataReporter$SomeClass)
    at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:132)
    at com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:109)
    at com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:613)
    at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:724)
    at com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ObjectArraySerializer.read(DefaultArraySerializers.java:338)
    at com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ObjectArraySerializer.read(DefaultArraySerializers.java:293)
    at com.esotericsoftware.kryo.Kryo.readObjectOrNull(Kryo.java:702)
    at com.esotericsoftware.kryo.serializers.FieldSerializer$ObjectField.read(FieldSerializer.java:521)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:221)
    at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:629)

Si la classe ci-dessus est mise en œuvre sans paramétrage (c'est à dire, la elements tableau déclaré en tant que String[]), la désérialisation fonctionne comme prévu.

Des idées?

  • Pouvez-vous poster le 'SomeClass"s Code ici? Je me souviens que dans Kryo, vous devez enregistrer toutes les classes qui peuvent être sérialisés (par exemple, si vous classe ArrayList, il doit être enregistré en tant que bien). Une autre question, faut-il travailler pour intentionnellement simple de la classe?
  • Il semble avoir à faire avec des génériques. La classe est paramétrable, c'est à dire SomeClass<T> avec une instance privée variable T[]. Si cette variable est supprimée, il fonctionne. Sinon, de nombreux types d'exceptions sont levées, en fonction de la variation.
  • Cela sonne comme vous devez utiliser SomeClass<T extends Serializable>
  • Il ne fonctionne pas encore comme ça. Veuillez consulter la version élargie de la question ci-dessus.
InformationsquelleAutor PNS | 2012-08-09