2012-08-09 55 views
5

我试图序列化和反序列化的自定义类的对象(比如,SomeClass,有一个默认的无参数的构造函数)到byte[]阵列,使用Kryo 2.19和默认的序列(FieldSerializer)/反序列化。通用Java序列化使用KRYO

序列化似乎工作正常,但我得到各种反序列化异常,具体取决于SomeClass的实际实现。

的代码看起来是这样的:

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); 

我收到例外的一个例子是:

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) 

看来,参数化类型是有问题的反序列化。为了检验这一假设,这里是一个参数实现的SomeClassgetObject()

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); 
} 

这连载罚款,但反序列化抛出以下异常(观察一下字符串的第一个字母不属于例外的原因报道):

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) 

如果上述类而不参数实现(即,elements阵列声明为String[]),反序列化按预期工作。

任何想法?

+1

你可以在这里发布'SomeClass'的代码吗?我记得在Kryo中,你应该注册所有可以序列化的类(例如,如果你的类使用ArrayList,它也应该被注册)。另一个问题,它是否适用于故意简单的课程? – 2012-08-09 09:54:49

+0

这似乎与仿制药有关。该类是参数化的,即具有私有实例变量T []的SomeClass 。如果该变量被删除,它将起作用。否则,根据变化情况,会抛出许多类型的异常。 – PNS 2012-08-09 10:22:31

+1

这听起来像你应该使用'SomeClass ' – Dahaka 2012-08-09 10:31:51

回答

0

确保您使用相同的类版本序列化和反序列化。如果您使用一个类版本进行序列化并使用不同的类版本(例如添加或删除字段后),则可能会发生此错误。并不意味着它只能在这种情况下发生。