具有不同Java版本的不同serialVersionUID

时间:2015-09-01 13:17:24

标签: java deserialization

我对Java序列化/反序列化有一个奇怪的问题。

除了序列化的所有其他问题以及serialVersionUID的正确用法之外,这种行为对我来说是全新的:

在我的软件运行的一台机器上(openSuse 13.1),更新将Java版本切换为Java 8.现在,如果我尝试重新打开软件的项目文件,我会得到一个java.io.InvalidClassException(这是一个序列化的Java Object)因为其中一个类具有错误的serialVersionUID。奇怪的是,这些类是来自外部库的类,并且几个月没有更改(但没有硬编码的serialVersionUID字段)。

如果我在该计算机上切换回Java 7,则不会发生错误。我可以使用openSuse 13.1 + Java 8在其他机器上重现该错误,但不能使用带有Java 8(或Java 7)的Windows或其他Linux发行版(如Ubuntu)的机器重现该错误。

在所有机器上安装了正式的sun / oracle JRE包。

那么,任何人都可以随时面对这个问题吗?我不认为这是Java 8中的错误,因为它只发生在openSuse 13.1计算机上。但是,openSuse的人怎么会搞乱他们的系统,java会像以前一样以不同的方式散列类(因为Java在新版本中没有改变过程)?

编辑: 要清楚,导致问题的类来自外部库。它在一个月内没有变化。并且解决方案不能定义serialVersionUID,因为该错误具有一些其他来源并且仍然存在。我认为,它不会停止在这个类,它将影响我使用的库中没有定义serialVersionUID的所有类

EDIT2: 这是确切的错误:

java.io.InvalidClassException: edu.uci.ics.jung.graph.util.Pair; local class incompatible: stream classdesc serialVersionUID = 7664847375082415686, local class serialVersionUID = -638192081897624765 

在我可以测试的所有其他机器上,该类具有哈希的serialVersionUID 7664847375082415686,只有openSuse 13.1 + Java 8得到的结果为-638192081897624765

2 个答案:

答案 0 :(得分:1)

  

有人在任何时候都遇到过这个问题吗?

你没有找到这个问题你做得很好。所有IDE都有一个带有serialVersionUID AFAIK的Serializable类的警告。这是一个常见问题,或者更确切地说,人们常常对serialVersionUID进行硬编码,因此他们不会看到它。注意:eclipse和Oracle JDK为相同版本的Java生成不同的UID。

  

因为它只发生在openSuse 13.1机器上。

这将是非常令人惊讶的。相同版本的Java应该在每个操作系统上生成相同的serialVersionUID。

注意:您可以将serialVersionUID设置为您需要的任何内容。例如假设您需要读取具有给定serialVersionUID的对象,您可以将其设置为expect UID,它将尝试读取您想要的任何版本。

答案 1 :(得分:0)

我们发现我们问题的根源是因为我们在后台运行了一个使用旧版Java编译的活动服务。此服务已设置为自动启动。因此,重新启动计算机不明显的原因。这是我们的软件卸载程序出现故障的结果。我们经常在我们的机器上安装构建版本来测试我们软件的现场版本。在这种特殊情况下,在一台机器上有一个与我们的软件冲突的有效服务;即使我们是从Eclipse运行它。

我建议任何遇到类似问题的人来验证旧服务不会造成冲突。确保卸载或禁用可疑服务,然后重试。