Tôi cố gắng để serialize và deserialize đối tượng của một lớp tùy chỉnh (ví dụ, SomeClass
, có một mặc định không-args constructor) vào một mảng byte[]
, sử dụng Kryo 2.19
và serializer mặc định (FieldSerializer
).Generic Java serialization/deserialization sử dụng Kryo
Việc tuần tự hóa dường như hoạt động OK, nhưng tôi nhận được nhiều ngoại lệ khác nhau trong quá trình deserialization, tùy thuộc vào việc triển khai thực tế SomeClass
.
Mã này trông giống như sau:
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);
Một ví dụ về các trường hợp ngoại lệ Tôi nhận được là:
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)
Dường như các loại tham số là có vấn đề để deserialize. Để kiểm tra giả thiết này, đây là một thực hiện tham số của SomeClass
và 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);
}
này serializes tốt, nhưng deserialization ném ngoại lệ sau (quan sát cách chữ cái đầu tiên của chuỗi là không được báo cáo trong các nguyên nhân ngoại lệ):
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)
Nếu lớp trên được thực hiện mà không tham số hóa (ví dụ, các mảng elements
khai báo là một String[]
), deserialization hoạt động như mong đợi.
Bất kỳ ý tưởng nào?
Bạn có thể đăng 'Mã của SomeClass' tại đây không? Tôi nhớ rằng trong Kryo bạn nên đăng ký tất cả các lớp có thể được tuần tự hóa (ví dụ, nếu lớp của bạn sử dụng ArrayList, nó cũng phải được đăng ký). Một câu hỏi khác, nó có hoạt động cho một lớp cố ý đơn giản không? –
Có vẻ như nó phải liên quan đến Generics. Lớp được tham số hóa, ví dụ: SomeClass với biến cá thể riêng T []. Nếu biến đó bị xóa, nó hoạt động. Nếu không, nhiều loại ngoại lệ được ném, tùy thuộc vào biến thể. –
PNS
Điều này nghe có vẻ như bạn nên sử dụng 'SomeClass' –
Dahaka