我正在编写一款需要远程绑定的应用程序,即将远程对象绑定到远程注册表。默认情况下,Java RMI Registry只在本地绑定,只有在相同JVM / host中绑定的远程对象。
我看到了一些解决方案,绕过这个问题,创建一个远程接口,将远程对象绑定在本地(此讨论的SO链接)。难道没有更优雅的方法来解决这个问题吗?也许我应该尝试使用其他提供程序的JNDI ??
这是一个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服务器可能仍会拒绝注册远程对象。但我对此表示怀疑。
LocatRegistry.createRegistry()
返回的注册表对象上调用 bind/rebind/unbind
时,但我看不出其相关性。 - user207421使用LDAP服务器代替RMI注册表。
我对此进行了更多的研究... 首先,如果您在两个服务器上拥有相同的代码库,那么应该很简单:
...
Registry registry = LocateRegistry.getRegistry("192.168.1.1", 1100);
registry.rebind("Hello, World!", myObj);
但是如果您需要将类加载到远程注册表中,很快就会遇到问题...您需要一个安全管理器:http://www.devx.com/getHelpOn/10MinuteSolution/20444
我仍然希望您可以发布代码示例或提供有关您情况的更多信息。
<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"。