如何发现序列化对象的serialVersionUID

时间:2012-01-12 18:36:58

标签: java serialization

简短问题:如何发现序列化形式的对象的serialVersionUID。

详细信息:我在Web应用程序的会话数据库中有一些序列化的Objects版本。对于其中一些对象,我未能在源代码中指定serialVersionUID,因此JVM为我创建了一个。我想发现保存的对象的serialVersionUID是什么,以便我可以在源文件中对其进行硬编码。

我可以轻松访问读取序列化数据。我已经完成并删除了当前版本的代码无法读取的(旧)会话,因此我知道每个序列化对象都与当前代码库匹配。

2 个答案:

答案 0 :(得分:2)

由于您拥有数据,因此您只需查看流中类名后面的八个八位字节,如grammar for Java Serialization所示

00000000: aced 0005 7372 0003 466f 6f00 0000 0000  ....sr..Foo.....
00000010: 0000 0102 0001 4c00 066d 794e 616d 6574  ......L..myNamet
00000020: 0012 4c6a 6176 612f 6c61 6e67 2f53 7472  ..Ljava/lang/Str
00000030: 696e 673b 7870 7400 044a 6f68 6e         ing;xpt..John

上面类的名称是“Foo”(没有包),serialVersionUID是1L。这是另一个例子:

00000000: aced 0005 7372 0011 7374 6163 6b6f 7665  ....sr..stackove
00000010: 7266 6c6f 772e 466f 6fff ffff ffff 7e3c  rflow.Foo.....~<
00000020: 1802 0001 4c00 066d 794e 616d 6574 0012  ....L..myNamet..
00000030: 4c6a 6176 612f 6c61 6e67 2f53 7472 696e  Ljava/lang/Strin
00000040: 673b 7870 7400 044a 6f68 6e              g;xpt..John

classname是stackoverflow.Foo。 serialVersionUID是0xff7e3c18,如此八位字节序列所示:

ff ffff fffff 7e3c 18

现在你所要做的就是查看文件格式,找出你的对象在每种情况下的位置,并阅读紧跟在 className 之后的 serialVersionUID 语法链接在上面。

答案 1 :(得分:1)

对我有用的是使用ObjectStreamClass.lookup(class)。

我运行一个反序列化数据库中所有会话对象的方法。然后我在我感兴趣的每个类上运行ObjectStreamClass.lookup()。它为我提供了一个ObjectStreamClass对象。 ObjectStreamClass对象包含类名和serialVersionUID。

我将获取该输出并相应地修改我的源文件。