几个月前,我将一个 java.io.Serializable 对象序列化到一个文件中。现在我需要阅读内容,但从那以后 serialVersionUID 发生了变化,现在我收到“类不兼容”错误。我知道所有数据成员都没有改变,所以唯一的障碍是 serialVersionUID 检查。
有没有办法禁用检查或修改二进制文件中的 serialVersionUID?
澄清
这个问题假设我无法编辑源。有没有办法破解 .class 文件或破解序列化的目标文件(使用十六进制编辑器并在某个偏移量处更改值)?
几个月前,我将一个 java.io.Serializable 对象序列化到一个文件中。现在我需要阅读内容,但从那以后 serialVersionUID 发生了变化,现在我收到“类不兼容”错误。我知道所有数据成员都没有改变,所以唯一的障碍是 serialVersionUID 检查。
有没有办法禁用检查或修改二进制文件中的 serialVersionUID?
澄清
这个问题假设我无法编辑源。有没有办法破解 .class 文件或破解序列化的目标文件(使用十六进制编辑器并在某个偏移量处更改值)?
为什么不按照序列化文档中的说明修改当前版本中的 serialVersionUID ?
作为 hack,您可以使用 serialver 工具生成您的 jvm 可能正在使用的 serialVer:
serialver -classpath 无论 com.foo.bar.MyClass
如果您随后在您的类中手动设置 serialVerUID,它应该匹配并且您应该能够加载,假设您没有以使类无效的方式更改类。
我最近发现自己处于类似的情况——我有一些我必须阅读的序列化对象,serialVersionUID
这些对象与最新版本不同,在我的情况下,serialVersionUID
文件中存储了几个不同的 s 用于同一类(显然存储在不同时间)。所以我没有修改类和设置它的奢侈serialVersionUID
;我实际上不得不进入并修改存储的数据。
我发现(通过阅读 java.io 源代码)是通过首先存储类名(使用writeUTF()
)然后在使用后立即writeLong()
保存serialVersionUID
.
我的解决方案是捕获异常然后返回,查找类名,并在类名之后立即将旧的替换serialVersionUID
为新的。
据记载,序列化不打算用于持久化数据。为了取回该数据,您需要将您的 JVM 版本降级到用于输出该数据的版本。
为了将来参考,不要使用序列化在 JVM 的会话之间持久化数据。