【发布时间】:2012-06-11 18:59:55
【问题描述】:
我正在研究 Java 序列化机制中的不同选项,以便在我们的类结构中实现版本容错存储的灵活性(并且提倡使用不同的机制,您无需告诉我)。
例如,如果只需要向后兼容,默认的序列化机制可以处理添加和删除字段。
但事实证明,重命名一个类或将其移动到不同的包要困难得多。我在this question 中发现,通过继承 ObjectInputStream 并覆盖 readClassDescriptor(),我能够进行简单的类重命名和/或移动包:
if (resultClassDescriptor.getName().equals("package.OldClass"))
resultClassDescriptor = ObjectStreamClass.lookup(newpackage.NewClass.class);
这对于简单的重命名很好。但是,如果您随后尝试添加或删除字段,则会收到 java.io.StreamCorruptedException。更糟糕的是,即使添加或删除了一个字段,并且然后您重命名该类,也会发生这种情况,这可能会导致多个开发人员或多个签入出现问题。
根据我所做的一些阅读,我尝试了一些覆盖resolveClass()的方法,我们的想法是我们正确地将名称重新指向新类,但不加载旧类本身并轰炸字段更改.但这来自对序列化机制的一些细节的非常模糊的理解,我什至不确定我是否在吠叫正确的树。
所以 2 个精确的问题:
- 为什么使用 readClassDescriptor() 重新指向类名会导致 反序列化在正常、兼容的类更改上失败?
- 有没有办法使用 resolveClass() 或其他机制来绕过 这并允许类进化(添加和删除字段)并成为 重命名/重新包装?
我四处寻找,找不到关于 SO 的等效问题。无论如何,如果存在这样的问题,请向我指出,但请仔细阅读该问题,除非另一个问题真正回答了我的确切问题,否则您不会关闭我。
【问题讨论】:
-
你找到解决办法了吗?
-
@orbfish 如果你发现了,请分享你的解决方案
-
@enthu-man 不知何故我错过了关闭它,已经很长时间了,我不再有问题的代码。这里有3个好看的解决方案,我会尝试,如果你找到一个可行的,我会接受它;)
标签: java serialization version-control version deserialization