Ich versuche Objekte einer benutzerdefinierten Klasse zu serialisieren und deserialisieren (sagen wir, SomeClass
, eine Standard mit no-args Konstruktor) zu einem byte[]
Array, mit Kryo 2.19
und die Standard-Serializer (FieldSerializer
).Generisches Java Serialisierung/Deserialisierung mit Kryo
Serialisierung scheint in Ordnung zu sein, aber ich bekomme verschiedene Ausnahmen in der Deserialisierung, abhängig von der tatsächlichen Implementierung von SomeClass
.
Der Code sieht wie folgt aus etwas:
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);
Ein Beispiel für die Ausnahmen Ich erhalte ist:
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)
Es scheint, dass parametrisierte Typen problematisch deserialisiert sind. Um diese Annahme zu testen, ist hier eine parametrisierte Implementierung von SomeClass
und 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);
}
Dieser serialisiert in Ordnung, aber Deserialisierung wirft die folgende Ausnahme (beobachten, wie die ersten Buchstaben der Zeichenkette nicht in der Ausnahme Ursache gemeldet wird):
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)
Wenn die obige Klasse ohne Parametrierung implementiert ist (dh die elements
Array deklariert als String[]
), Deserialisierung wie erwartet funktioniert.
Irgendwelche Ideen?
Können Sie den 'SomeClass'-Code hier posten? Ich erinnere mich, dass Sie in Kryo alle Klassen registrieren sollten, die serialisiert werden können (Beispiel: Wenn Ihre Klasse ArrayList verwendet, sollte sie ebenfalls registriert werden). Eine andere Frage, funktioniert es für absichtlich einfache Klasse? –
Es scheint mit Generika zu tun zu haben. Die Klasse ist parametrisiert, d. H. SomeClass mit einer privaten Instanzvariablen T []. Wenn diese Variable entfernt wird, funktioniert es. Andernfalls werden abhängig von der Variation zahlreiche Arten von Ausnahmen ausgelöst. –
PNS
Das hört sich so an, als müssten Sie 'SomeClass' –
Dahaka