如何反序列化OSGi中的实现类

时间:2010-03-18 22:33:11

标签: java serialization osgi

在基于eRCP OSGi的应用程序中,用户可以按下按钮并转到类似于Windows或Mac OS X的锁定屏幕。当发生这种情况时,应用程序的当前状态被序列化为文件并且控制权被移交到锁屏。在这个移动应用程序中,内存非常紧凑,因此我们需要在锁定屏幕出现时摆脱原始视图/控制器。

这很好用,我们最终得到一个二进制序列化文件。用户重新登录后,将再次读入该文件并恢复应用程序的原始状态。当序列化的控制器包含对来自不同包的对象的引用时,这也可以正常工作,除了。在我的具体情况下,原始控制器(来自捆绑包A)可以调用Web服务并获得结果。没什么好看的,只是一个简单的价值持有者类中的一些字符串和数字。但是,控制器只将其视为Result接口;实际的运行时对象(ResultImpl)是在不同的bundle(bundle B,webservice客户端实现)中定义和创建的,并通过服务调用返回。

当反序列化现在尝试从文件解冻控制器时,它会抛出ClassNotFound异常,抱怨无法反序列化结果对象,因为从bundle A调用反序列化,它无法看到{来自B组的{1}}类。

关于如何解决这个问题的任何想法?我唯一能想到的就是将所有单个值克隆到另一个对象中,在控制器的包中定义,但这看起来很麻烦。

2 个答案:

答案 0 :(得分:4)

使用序列化通常很脆弱,您不应该使用它来持久存储数据,因为类中的更改会导致这些图像被破坏。如果您可以将信息保持为中性存储格式(文本,XML,json),然后您可以使用该信息在运行时重新创建所需的clases和绑定,那会更好。这也为您的捆绑和布局提供了更大的灵活性,因为您不再依赖于特定的实现。

那就是说,你得到这些错误的原因是因为默认(de)序列化使用当前的类加载器来加载时解析类,并且并非所有类都在同一个包中(因此也是类加载器)。即使你有两个具有完全相同名称和包的类,如果从不同的类加载器加载它们,你最终会得到不同的(不兼容的)类,这就是这里发生的事情。

答案 1 :(得分:1)

您需要编写ObjectInputStream的子类,它提供resolveClass的实现,能够从OSGi类加载器中检索定义。