所以我看到在Java 9中已经删除了通过RMI的HTTP隧道。
我们销售在Tomcat中运行的商业Java软件。我们的客户将其安装在Mac、Windows和Linux服务器上。然后,公众可以通过JavaSwing客户端接口访问该软件。它使用RMI与服务器软件进行通信。
我们的大多数客户都有防火墙,防止访问80/443以外的任何端口上的服务器。这对于Java 8和更早版本来说不是问题,它可以通过动态端口使用RMI,或者在防火墙阻止访问时切换到HTTP。
然而,删除Java 9中的HTTP代理功能意味着我们的大多数客户将无法再使用我们目前的软件架构。对于我们的客户来说,将防火墙和服务器配置为从公众进行SSH访问是不切实际和不安全的,尤其是对于运行Windows服务器的客户。
这是否意味着我们需要重写我们的应用程序架构,以使用RMI之外的一些网络协议?或者有没有一种方法可以将RMI保持在Java 9中?完全放弃RMI将需要完全重写面向用户的应用程序代码,这不是一个经济高效的选择。
似乎JDK-8023862已经否决了RMI的HTTP代理,Java8的发行说明中也提到了这一点。
正如#JDK8180642中所建议的,它还询问了从RMI中删除HTTP代理实现的替代方案。其中一种选择是使用ssh通过代理进行隧道传输。
使用ssh建立一个通过代理进行隧道传输的本地端口到远程机器。该连接将比HTTP代理实现更具功能性。
在链接中,您可以在上找到一篇文章,介绍如何通过本地防火墙发出Java RMI调用,它还建议其他实现,如SOCKS和套接字工厂。
所以我看到在Java 9中已经删除了通过RMI的HTTP隧道。
这并不奇怪。这是一个糟糕的解决方案,单向,性能损失10倍。
这是否意味着RMI已经死了?
否。从1.1开始,它就是Java的一部分,从那时起,20年前,Java的历史是向后兼容性的一个显著记录。ABI兼容性的最后一次破坏是当他们在1.0和1.1之间更改AWT事件模型时。如果RMI被从Java中删除,那将是令人惊讶的,并且在删除RMI/HTTP隧道中没有任何东西可以证明你有理由得出这个结论。
我们目前广泛使用RMI来构建客户端-服务器用户界面。对于我们的客户端来说,防火墙阻塞动态端口是很常见的,所以我们恢复到HTTP隧道。
您肯定需要另一种隧道解决方案。想到了宋承宪。
我们应该如何在Java 9中处理此问题?
请参阅上文。
完全放弃RMI将需要完全重写面向用户的应用程序代码。
没有任何迹象表明这种必要性。
关于RMI端口使用:
- 默认情况下有端口共享
- 导出时可以指定端口,如果扩展了
UnicastRemoteObject
,则可以通过super(port,...)
指定,如果不扩展,则通过UnicastRemoteObject.exportObject(object, port, ...)
指定
例如,如果您从同一JVM导出注册表,然后导出更多远程对象,它们将默认共享端口1099,或者您可以明确强制它。
如果使用RMIServerSocketFactory
,则需要为其提供适当的equals()
方法来保留这些语义。