当前位置: 首页 > 面试题库 >

如何处理其程序包已更改的Java序列化对象?

范文昌
2023-03-14
问题内容

我有一个Java类,该类存储在HttpSession对象中,该对象在集群环境中的服务器之间进行了序列化和传输。为了便于说明,我们将此类称为“人员”。

在改进代码的过程中,该类从“ com.acme.Person”移动到“
com.acme.entity.Person”。在内部,该类保持完全相同(相同的字段,相同的方法,相同的所有内容)。

问题是我们有两组服务器同时运行旧代码和新代码。具有旧代码的服务器已序列化HttpSession对象,当新代码将其反序列化时,它将引发ClassNotFoundException,因为它找不到对com.acme.Person的旧引用。在这一点上,处理起来很容易,因为我们可以使用新包重新创建对象。问题在于,新服务器中的HttpSession将使用对com.acme.entity.Person的新引用来序列化该对象,并且在运行旧代码的服务器中对该序列进行反序列化时,将引发另一个异常。在这一点上,我们不能再处理这个异常了。

在这种情况下,最好的策略是什么?有没有一种方法可以告诉新服务器使用对旧程序包的引用来序列化该对象,并将对旧程序包的引用反序列化为新的程序包?一旦所有服务器都运行新代码,我们将如何过渡到使用新软件包并忘记旧软件包?


问题答案:

我发现这篇博客文章声称有解决方案,尽管并没有清楚说明。

实际的意思是,您创建了一个子类,ObjectInputStream该子类将覆盖readClassDescriptor方法以执行以下操作:

@Override
protected java.io.ObjectStreamClass readClassDescriptor() 
        throws IOException, ClassNotFoundException {
    ObjectStreamClass desc = super.readClassDescriptor();
    if (desc.getName().equals("oldpkg.Widget")) {
        return ObjectStreamClass.lookup(newpkg.Widget.class);
    }
    return desc;
};

我的建议是: 支持旧版本的软件读取由新版本序列化的数据的情况。

  • 这是一个鼓励(实际上是强迫)人们升级到最新版本代码库的好机会。一般而言,早日发生此事符合 所有人的 利益。

  • 如果因为其他原因而迫使人们进行升级为时尚早,那么(IMO)您应该认真考虑 撤消 对类/html" target="_blank">程序包名称的更改。请等待,直到您有了明确的升级策略/计划:1)技术上合理,并且2)所有利益相关者都可以接受。



 类似资料:
  • 有一个类实现,但在第一个版本中没有定义。在下一个版本中,我提供了。 现在的问题是,每当我试图反序列化之前存储的对象时,都会出现错误: 静态最终长serialVersionUID=4061053075992556495L;但需要com.example.android.user:静态final long serialVersionUID=-1079331593441085712L;

  • 我现在还在下面提供了一个示例。 我正在使用一个大型应用程序,它将序列化对象(实现可序列化,而不是可执行)从客户机发送到服务器。不幸的是,我们现在有一种情况,即现有字段完全改变了类型,这破坏了序列化。 谢谢你的建议。 5月20日更新-以下示例源--TestData中的字段“number”从旧版本中的“int”变为新版本中的“long”。注新版本的TestData中没有调用readObject(),因

  • 问题内容: 我正在尝试用Java创建一个简单的图像编辑程序。我制作了一个对象,其中包含有关正在编辑的图像的所有信息(一些基本属性,所应用的效果列表,层列表等),我想要一种简单的方法将其保存到磁盘,以便稍后再次打开。 我发现使用Java的defualt 接口可能正是我想要的,我可以将整个对象写到文件中,稍后再读回内存中。但是,包括和不能序列化(其他所有方法都可以)。 我知道可以重写和方法,但我从未这

  • 问题内容: 考虑我有一个Singleton类,定义如下。 根据我的上述定义满足了Singleton的要求。添加的唯一额外行为是该类实现了可序列化的接口。 如果另一个类X获得了单例的实例并将其写入文件,然后在以后将其反序列化以获取另一个实例,则将有两个实例违反了Singleton原理。 我该如何避免这种情况,或者我在上述定义本身中错了。 问题答案: 最好的方法是使用枚举单例模式: 这样可以保证对象的

  • 我正在使用第三方JSON API,它返回如下数据: 我使用Java Jackson将此JSON字符串反序列化为POJO对象,字段声明为:

  • 是否有一种方法可以从数据库中读取序列化对象。ser文件并更新或删除已序列化的对象之一? 下面是我的代码,读取的对象类型'驱动程序':