具有不同Java版本的不同serialVersionUID

具有不同Java版本的不同serialVersionUID,java,deserialization,Java,Deserialization,我对Java序列化/反序列化有一个奇怪的问题 除了序列化和正确使用serialVersionUIDs的所有其他问题外,这种行为对我来说是全新的: 在我的软件运行的一台机器上(openSuse 13.1),一次更新将Java版本切换到Java 8。现在,如果我试图重新打开软件的项目文件(这是一个序列化的java对象),因为其中一个包含的类具有错误的serialVersionUID,那么我会得到一个java.io.InvalidClassException。奇怪的是,这些类是一个来自外部库的类,几个

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

除了序列化和正确使用serialVersionUIDs的所有其他问题外,这种行为对我来说是全新的:

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

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

在所有计算机上都安装了正式的sun/oracle JRE软件包

那么,有人在任何时候都面临过这个问题吗?我不认为这是Java8中的错误,因为它只发生在OpenSUSE13.1机器上。但是openSuse的家伙们怎么会把他们的系统搞得一团糟,以至于java会像以前一样以不同的方式对类进行散列(因为java在新版本中没有改变这个过程)

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

编辑2: 下面是确切的错误:

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得到的结果是-63819208897624765

有人在任何时候都面临过这个问题吗

你没有发现这个问题,你做得很好。所有IDE都有一个针对serialVersionUID AFAIK的可序列化类的警告。这是一个常见的问题,或者更确切地说,人们通常会硬编码serialVersionUID,这样他们就看不到它了。注意:eclipse和Oracle JDK为同一版本的Java生成不同的UID

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

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


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

不久前,我们发现问题的根源是因为我们在后台运行了一个使用旧版本Java编译的活动服务。此服务已设置为自动启动。因此,由于明显的原因,重新启动计算机不起作用。这是由于我们的软件卸载程序存在缺陷造成的。我们经常在我们的机器上安装构建来测试我们软件的现场版本。在这个特殊的案例中,在一台机器中有一个与我们的软件冲突的活动服务;即使我们在Eclipse上运行它


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

但这是JRE的问题,而不是JDK的问题,因为我在没有任何JDK参与的情况下从JAR文件运行软件。是的,我知道,但现在就发生在这里。我不知道发生了什么。。。由于该类位于库中,我必须在库的代码中更改它,并将其构建为新的。但我认为它不会因为这个库中的这个类而停止。我自己的班级有一个“硬编码”serialVersionUID@Thargor同样,同一版本的JDK和JRE在所有操作系统上的行为应该相同。执行此操作的代码与平台无关。我知道=)。这就是我在这里问这个问题的原因。该项目始于Java 5,到目前为止,这从来都不是一个问题,因为Java没有改变散列类的方法(使用SHA-1算法,它有望在Java中实现,而不是使用system methode)@Thargor这是非常流行的Java字节码签名摘要,散列独立存储在清单文件中,这是因为在更新java版本之前,某些用户已经使用过该软件。让用户在进行主要升级之前启动。这会对运行时类的哈希方法产生什么影响?不会,即使哈希更改,代码也会有不同的签名。因此我不明白你的意思。我们遇到了类似的问题。带Java 8的Windows 7失败,但我的带Windows 8和Java 8的机器工作正常。当我们使用Java6时,这不是一个问题。在我们的例子中,失败发生在RMIC类被加载时。