将远程对象反序列化为最窄的可访问类
在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个jar子都在一个类加载器中,一切都运行良好。
但客户端和服务器位于不同的JVM中,而:
- JVM-1包含: server.jar , shared.jar
- JVM-2包含: client.jar , shared.jar
客户端调用服务器。 服务器返回MyConcreteClass ,Java无法反序列化它( ClassNotFoundException )。
我想做什么:
- 服务器序列化类并发送数据和类的祖先集
- 客户端找到它可能反序列化的最窄的祖先。
一切都很好:我们在客户端上有MyParent实例,这就是我们需要的。
我不敢相信没有这样的引擎。 你知道吗? 我确信远程呼叫应尽可能与本地呼叫类似。
谢谢。
实际上我找到了解决方案并制作了一个特殊的包来支持它:
- MyParent必须使用特殊的SerializableParent注释标记。 此注释意味着任何子类都应该“转换”为MyParent,然后远程引擎可以将其序列化并通过线路传输。 通过设置此注释,您不仅告诉系统MyParent存在于远程JVM上,而且层次结构树也不需要多态:如果子类覆盖父方法,它将无法在远程系统上使用,因为只能发送数据而不能发送代码。
- 在发送结果引擎之前,应该找到注释为SerializableParent的最窄的祖先
- 应该序列化为XML的对象(例如,使用XStream),并使用父类作为child的别名反序列化。 为了防止“未知字段”错误,必须通过覆盖wrapMapper和shouldSerializeMember来攻击Xstream。
- 你有“可序列化的父母”被转移
实现java.io.Serializable接口的对象可以使用writeReplace()和readResolve()方法将另一个对象替换为序列化/反序列化的对象。 我可以看到这被用来解决你的问题。 但是,我自己没试过。