【问题标题】:Deserialize remote object to the narrowest accessible class将远程对象反序列化为最窄的可访问类
【发布时间】:2012-05-02 05:40:10
【问题描述】:

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.jarshared.jar
  • JVM-2 包含:client.jarshared.jar

客户端调用服务器。服务器返回 MyConcreteClass 并且 Java 无法对其进行反序列化 (ClassNotFoundException)。


我想做什么:

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

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

我不敢相信没有这样的引擎。你认识一个吗? 我确信远程呼叫应该尽可能类似于本地呼叫。

谢谢。

【问题讨论】:

标签: java spring serialization rmi


【解决方案1】:

其实我找到了解决方案并做了一个特殊的包来支持它:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      • 2013-02-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多