【问题标题】:Setting host address of rmi object [closed]设置 rmi 对象的主机地址
【发布时间】:2013-01-10 21:47:55
【问题描述】:

我想在 rmi 中设置远程对象的主机地址。是否可以在存根中设置此 IP 地址?

NOT:我知道我可以使用 ThreadLocalRmiClientSocket 工厂制造一个技巧,但我不想使用它。

【问题讨论】:

  • 出于什么目的?生成的存根只有 65536 分之一的工作机会,即使假设已通过新的 host:port 导出了实现相同远程接口的远程对象。
  • 嗨,EJP 我正在获取远程服务器对象。然后我正在创建一个客户端并注册这个客户端。像这样 server.register(client);在上述情况下,当我 ping 服务器时,一切正常。但是当我从服务器 ping 客户端时它不起作用。因为客户端有两个以太网卡并且在客户端对象中嵌入了无效的主机地址。所以 ping 无效主机地址失败。

标签: java ip-address rmi host stub


【解决方案1】:

在远程存根中,您需要为protected RemoteRef ref 字段设置一个新值。所有远程通信都通过这个对象。由于该字段受到保护,因此您只能在从 RMI 存根派生的自己的类中简单地执行此操作。

不幸的是 RemoteRef 是一个没有公共实现的接口。您可以查看现有的OpenJDK implementation。从那里可以看出有一个实现sun.rmi.server.UnicastRef 需要LiveRef,而那个实现需要EndpointEndpoint 已经比较容易理解了。您可能需要在代码中复制这些类的功能。

为确保存根类确实存在,请使用 rmic 生成它,甚至可以使用 -keepgenerated,这样您就可以检查该字段确实存在的源代码 - 谁知道特定实现的细节。

一般来说,这绝不是一个优雅而简单的解决方案,但它应该可以工作。

扩展:由于这一切看起来相当复杂,我建议获取一个新的有效存根,该存根指向远程服务的更新位置并窃取ref 字段的值从中。这似乎相对容易做到,如果当前存根与某些数据结构纠缠在一起,因此您无法轻松替换它,这可能是合理的。存根本身并不关心主机、端口、对象 id 或 watsoever,只要远程端继续实现相同的远程合同 - 只有它的 RemoteRef 会。存根依赖于RemoteRef.invoke

【讨论】:

  • 完全没有必要。看我的回答。
  • 是的,看我的回复。 @EJP 解决方案仅适用于代表本地对象的存根。
  • 这完全不正确。它适用于从您设置该系统属性的 JVM 导出的所有存根,以及它们可能最终到达的任何地方,无论是本地的还是远程的。您已经很好地分析了代码,但您似乎没有掌握更广泛的问题。您的答案既非必要也不充分,除非在我在答案下方列举的极不可能的情况下,否则它不会起作用。显然你还没有尝试过。
【解决方案2】:

在导出任何远程对象之前,您需要在服务器 JVM 中适当地设置系统属性“java.rmi.server.hostname”。然后在导出时创建该值时将其嵌入到存根中。

【讨论】:

  • 他在问如何更改 remote 对象的地址 in a stub - 代表另一台机器上的对象的地址,应该使用哪个主机名现在有所不同。我假设,他想在知道对象已迁移到其他已知位置后更改此主机名。您解释如何更改本地服务器的主机名。
  • @AudriusMeškauskas 在这种情况下,这个问题没有任何意义。只有在以下情况下,直接在存根中更改端点地址才有效:(a) JVM 中有一个远程对象位于该主机:端口,(b) 实现了相同的远程接口 (c)使用相同的 objectID 导出,您无法控制。不太可能。
  • @EJB 我认为这是一种故障转移,并且有一个完全相同的服务在该新位置运行。
  • @AudriusMeškauskas 使用相同的 objectID?如果他能弄清楚如何做到这一点,那么他肯定也能用 Endpoints 弄清楚这些东西吗?如果这是实际问题,那么 OP 应该这么说。有适当的解决方案,不涉及以未记录的方式重写存根。
  • 嗨,Audrius 是对的,我要求更改嵌入式 IP 地址。设置属性仅更改服务器对象主机地址。但我需要知道如何更改不是服务器对象的对象的嵌入地址。
猜你喜欢
  • 1970-01-01
  • 2012-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多