【发布时间】:2016-10-26 03:54:18
【问题描述】:
我已经用 Java 实现了我自己的序列化程序。让我们称之为 abcSerializer。我要序列化的对象是 abc,它是一个 Google Protocol Buffer 类。
我正在尝试使用 kryo 框架来序列化这个对象。经过谷歌的一些研究和阅读后,我决定继续使用 kryo 序列化程序。我本身没有指定任何序列化程序,所以我假设 kryo 选择了一个默认的序列化程序。
public class abcSerializer implements AttributeSerializer <abc> {
public abcSerializer() {
kryo = new Kryo();
}
public static Kryo getKryo() {
return kryo;
}
@Override
public abc read(byte[] buffer) {
abc xyz = null;
ByteArrayInputStream abcsStream = new ByteArrayInputStream(buffer);
Input abcsStreamInput = new Input(abcsStream);
xyz = getKryo().readObject(abcsStreamInput, abc.class);
return xyz;
}
@Override
public void write(byte[] buffer, abc abc) {
ByteArrayOutputStream abcStream = new ByteArrayOutputStream();
Output abcOutput = new Output(abcStream);
getKryo().writeObject(abcOutput, abc);
abcOutput.toBytes()
}
}
当我执行 writeObject 时,一切都很好。但是,当我执行 readObject 时问题就来了。 Kyro 抛出以下异常。
com.esotericsoftware.kryo.KryoException: Class cannot be created (missing no-arg constructor): java.util.Collections$Unmodifiabljava.lang.IllegalStateException: Encountered error in deserializer [null value returned]. Check serializer compatibility.eRandomAccessList
上面的异常几乎是不言自明的。
kryo 文档如下。 ""特定类型的序列化程序使用 Java 代码创建该类型的新实例。诸如 FieldSerializer 之类的序列化器是通用的,必须处理创建任何类的新实例。默认情况下,如果一个类具有零参数构造函数,则通过 ReflectASM 或反射调用它,否则将引发异常。如果零参数构造函数是私有的,则尝试使用 setAccessible 通过反射访问它。如果这是可以接受的,私有零参数构造函数是允许 Kryo 创建类的实例而不影响公共 API 的好方法。""
现在,我有两个问题。
1) google 协议缓冲区生成的类确实有一个无参数构造函数。然而,这似乎是一个私人的。这是一个问题和上述 kryo 异常的根本原因吗?
2) 如果是这样,如何处理上述问题?我的意思是,我如何编写自己的序列化程序并仍然用于序列化 google 协议缓冲区对象数据?
【问题讨论】:
标签: serialization protocol-buffers kryo