JEP 385:弃用 RMI 激活以进行移除
总结
弃用 RMI Activation 机制,以便日后移除。RMI Activation 是 RMI 中一个过时的部分,自 Java 8 起已成为可选项。RMI 的其他部分不会被弃用。
动机
RMI 激活机制已实际上过时
在过去的至少十年间,分布式系统一直基于 Web 技术。在 Web 服务领域,有关穿越防火墙、过滤请求、身份验证和安全性的问题都得到了解决。资源的惰性实例化由负载均衡器、编排工具和容器处理。这些机制均未出现在用于分布式系统的 RMI 激活模型中。
RMI 激活大部分已被弃用
RMI 激活的使用量极低。没有任何证据表明有新的应用程序正在编写以使用 RMI 激活,并且有证据表明很少有现有应用程序使用 RMI 激活。对各种开源代码库的搜索显示,几乎未提到任何与激活相关的 API。多年来,没有收到任何外部生成的关于 RMI 激活的错误报告。在 Stack Overflow 问答网站上的查询显示,大约有 2,200 个关于 RMI 的问题,但其中只有 14 个提到了“激活”。JavaRanch 论坛上最近一篇关于 RMI 激活的问题发布于 2003 年,而该论坛每天都会收到几十篇关于其他主题的帖子。
RMI 激活功能在 Java 8 中变为可选。对于这一规范变更没有任何反对意见,也没有关于激活功能可选性的任何错误报告。
RMI 激活会带来持续的维护负担
维护 RMI 激活作为 Java 平台的一部分会产生持续的维护成本。它增加了 RMI 的复杂性。RMI 仍在维护中,而 RMI 激活增加了该维护的费用。
RMI 激活在 JDK 中有一套测试。这些测试通常会调用 RMI 激活服务(rmid
)以及客户端和服务器的 JVM。这导致测试运行缓慢,并且这些测试的多进程性质会导致持续出现间歇性的、虚假的失败。
RMI 激活的规范、实现和测试都带来了持续的维护开销。移除 RMI 激活不会影响 RMI 的其他部分。移除 RMI 激活并不会降低 Java 对于开发者的使用价值,但确实可以减少 JDK 长期以来的维护成本。
描述
RMI 激活机制允许基于 RMI 的服务导出其有效性超过远程对象或包含该对象的 JVM 生命周期的存根。对于传统的(非可激活的)RMI,一旦远程对象被销毁,存根就会失效。从这种情况中恢复需要客户端实现复杂的错误处理逻辑。当客户端调用可激活存根上的方法时,RMI 激活服务会按需实例化远程对象,从而减轻了客户端处理无效存根的负担。这似乎是一种有价值的机制,然而,正如在动机部分所述,RMI 激活的实际使用量微乎其微。
此 JEP 将弃用 RMI 激活机制,以便日后删除。这需要对 Java 平台进行以下更改:
-
为位于 java.rmi.activation 包中的所有公共类和接口添加
@Deprecated(forRemoval=true)
。 -
在
java.rmi.activation
包声明中添加一个@deprecated
javadoc 标签及说明。 -
在 java.rmi 模块规范中添加关于 Activation 弃用的通知。
-
在 RMI 规范的 RMI Activation 章节中添加弃用通知。
JDK 还将做出以下更改:
-
为
com.sun.rmi.rmid.ExecOptionPermission
和ExecPermission
类以及com.sun.rmi.rmid
包添加@Deprecated(forRemoval=true)
。 -
修改 rmid 工具,以发出有关弃用的警告消息。
-
在 rmid 工具文档页面 中添加警告通知。这将包括关于
rmid
工具本身的弃用通知。由于此页面似乎是 JDK 中记录这些权限类的唯一位置,因此还将包括对com.sun.rmi.rmid
中权限类的弃用通知。
替代方案
保留 RMI 激活
另一种选择是像过去几年一样,保留 RMI Activation。但它会持续带来质量风险和维护负担。持续的成本不断累积,而这个基本上未被使用的机制为平台带来的价值微乎其微,因此这些成本是不合理的。
从 JDK 构建中移除 RMI 激活
RMI 激活是 Java 平台的可选部分,因此可以从 JDK 构建中省略。实际的实现可能会被移除,并替换为抛出 UnsupportedOperationException
的方法。相关的测试也可以被移除。
然而,JDK 是 Java 平台的参考实现,而参考实现需要包含所有可选功能,以便进行测试。因此,RMI 激活(Activation)实现和测试不能简单地从 JDK 中移除。而是需要由构建系统有条件地配置。在参考实现的构建中会包含激活功能,以便能够正确测试,而在生产版本中可能会省略该功能。
这会增加系统的复杂性。构建过程需要进行增强,以支持这两种模式。持续集成系统需要增加运行次数,以构建和测试两种配置。实现和测试仍然存在于系统中,必须持续进行维护。因此,从 JDK 构建中移除 RMI 激活并不会减轻总体的维护负担,而这正是此 JEP 的目标。
风险与假设
有可能第三方产品使用了 Activation,因此它们会受到其弃用和最终移除的影响。然而,考虑到过去几年中关于 Activation 变更收到的反馈很少,这种情况不太可能发生。Activation 仍然存在于早期的 JDK 发布版本中,其中一些版本具有长期支持。依赖于 Activation 的应用程序在迁移到更新的技术的同时,仍可以在一段时间内继续依赖现有的受支持 JDK。
Apache River 项目包含 RMI 和 Jini 技术的分支版本,其中包括一个激活机制。River 的这一部分依赖于 Java 的 java.rmi.activation
类型。从 Java 中移除 RMI 激活功能将阻止 River 项目迁移到最新版本的 Java,除非他们能够移除对 Java 类型的依赖。