将远程对象反序列化为最窄的可访问类

时间:2012-04-20 16:01:30

标签: java spring serialization rmi

shared.jar 我有:

abstract class MyParent {

}
abstract class MyClass {
   MyParent getFoo();
}

server.jar 包含

abstract class MyChild extends MyParent {

}
abstract class MyClassConcrete {
   MyParent getFoo() {return new MyChild();}
}

client.jar中

MyParent foo = myClass.getFoo();

如果所有3个罐子都在一个类加载器中,一切都运行良好。

但是客户端和服务器位于不同的JVM中:

  • JVM-1包含: server.jar shared.jar
  • JVM-2包含: client.jar shared.jar

客户端拨打服务器电话。服务器返回 MyConcreteClass ,Java无法反序列化它( ClassNotFoundException )。


我想做什么:

  • 服务器序列化类并发送数据和类的祖先集
  • 客户找到可能反序列化的最窄的祖先。

一切正常:我们在客户端上有 MyParent 的实例,这就是我们需要的。

我不敢相信没有这样的引擎。你知道吗? 我确信远程呼叫应尽可能与本地呼叫类似。

感谢。

2 个答案:

答案 0 :(得分:0)

实际上我找到了解决方案并制作了一个特殊的软件包来支持它:

  • MyParent 必须使用特殊的 SerializableParent 标注进行标记。此注释表示任何子类都应“转换”为 MyParent ,然后远程处理引擎可将其序列化并通过线路传输。通过设置此注释不仅可以告诉系统 MyParent 存在于远程JVM上,而且层次结构树也不需要多态性:如果子项覆盖父方法,它将无法在远程系统上使用,因为只有数据但代码可以被发送。
  • 在发送结果引擎之前,应该找到注释为 SerializableParent
  • 的最窄的祖先
  • 应该序列化为XML的对象(例如,使用XStream),并使用父类作为child的别名反序列化。为了防止“未知字段”错误,必须通过覆盖 wrapMapper shouldSerializeMember 来攻击Xstream。
  • 你有“可序列化的父母”被转移

答案 1 :(得分:0)

实现java.io.Serializable接口的对象可以使用writeReplace()和readResolve()方法将另一个对象替换为序列化/反序列化的对象。我可以看到这被用来解决你的问题。但是,我自己没试过。