远程RMI注册表

6

我正在编写一款需要远程绑定的应用程序,即将远程对象绑定到远程注册表。默认情况下,Java RMI Registry只在本地绑定,只有在相同JVM / host中绑定的远程对象。

我看到了一些解决方案,绕过这个问题,创建一个远程接口,将远程对象绑定在本地(此讨论的SO链接)。难道没有更优雅的方法来解决这个问题吗?也许我应该尝试使用其他提供程序的JNDI ??


你能发一个代码示例吗?我认为你的问题语言可能有点令人困惑。 - Jonathan S. Fisher
4个回答

3

这是一个hack,但您可以尝试在服务器上设置端口转发,使注册表服务器端口以一种使所有通过它的请求看起来像本地请求的方式暴露出来。

使用SSH做到这一点相当容易。在服务器上运行:

ssh localhost -N -L 1199:localhost:1099 -g

这不会运行一个命令 (-N),但会在本地机器上打开一个监听端口 1199,并将其转发到 localhost 上的端口 1099 (-L 1199:localhost:1099),并且可以从任何来源连接 (-g)。通过此隧道进行的连接将显示为来自 localhost 的端口 1099 到服务器。请注意,您还可以添加 -f 以使 SSH 在设置隧道后进入后台模式,在这种情况下,我建议还添加“-o ExitOnForwardFailure”以改善错误处理。

也可以使用 netcat 而不是 SSH 进行此操作,这将更简单、更高效,但我没有安装合适版本的 netcat。如果您已经安装了 socat,则也可以使用它进行操作:

socat TCP-LISTEN:1199,fork TCP:localhost:1099

现在,我不知道这些选项是否足够。这将打开网络级访问,但是rmiregistry服务器可能仍会拒绝注册远程对象。但我对此表示怀疑。


1
@exabrial:你能指出问题在哪里说了吗? - Tom Anderson
1
@exabrial 你在说什么?JVM不会“绕过TCP/IP协议栈来访问本地注册表”。 - user207421
1
@exabrial:我不明白为什么这个问题特别是一个编程问题。它更像是一个部署或配置问题。有编程解决方案,也有网络解决方案。虽然确实会存在非可移植性的风险,但这通常并不是一个问题。尽管如此,我承认我的解决方案只是一个权宜之计,而且并不优雅 - 这就是为什么我将其描述为一个hack! - Tom Anderson
1
@exabrial:因为你的答案并没有解决问题。问题是将一个机器上的一些对象放入另一个机器上的RMI注册表中。你的答案所提供的方法并没有实现这个目标 - Tom Anderson
1
@exabrial "其次,如果您的JVM知道注册表位于同一JVM中,则确实可以绕过操作系统。" 这是正确的 仅当 您在由 LocatRegistry.createRegistry() 返回的注册表对象上调用 bind/rebind/unbind 时,但我看不出其相关性。 - user207421
显示剩余2条评论

2

使用LDAP服务器代替RMI注册表。


@MarcosRoriz 当然可以。网络上有很多关于LDAP的教程。您需要获取、安装和运行LDAP服务器,并使用JNDI与之通信,而不是java.rmi.Naming或java.rmi.registry.Registry类。 - user207421

1

我对此进行了更多的研究... 首先,如果您在两个服务器上拥有相同的代码库,那么应该很简单:

...
Registry registry = LocateRegistry.getRegistry("192.168.1.1", 1100);
registry.rebind("Hello, World!", myObj);

但是如果您需要将类加载到远程注册表中,很快就会遇到问题...您需要一个安全管理器:http://www.devx.com/getHelpOn/10MinuteSolution/20444

我仍然希望您可以发布代码示例或提供有关您情况的更多信息。


3
错误。您只能在运行注册表的同一主机上绑定/重新绑定/取消绑定。 - user207421

-2
我已经完成了这个任务,但是我采用了一种非常不同的方法。我编写了普通的POJO和普通的Java接口,而没有涉及奇怪的抽象类、远程存根编译器或与Java RMI API相关的大量检查异常。然后我使用Spring Remoting连接所有内容,Spring负责RMI传输:
请看这里的手册: http://static.springsource.org/spring/docs/2.0.x/reference/remoting.html 这是一个将代理到远程注册表的bean示例:
<bean id="accountService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
    <property name="serviceUrl" value="rmi://HOST:1199/AccountService"/>
    <property name="serviceInterface" value="example.AccountService"/>
</bean>

这解决了你的问题,但可能并没有完全回答你的问题... Java 的旧 RMI API 已经相当陈旧了,Spring 让你可以使用 "纯粹的 Java"。


2
谢谢回复,但这不是我要找的。我正在寻找一种使用rmi接口解决此问题的方法。 - Marcos Roriz Junior
Tom:实际上我的回答是关于RMI的。我演示了一种替代方案,可以消除他所处的困境,从而有效地解决他的困境。 - Jonathan S. Fisher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接