JEP 320:移除 Java EE 和 CORBA 模块
概述
从 Java SE 平台和 JDK 中移除 Java EE 和 CORBA 模块。这些模块在 Java SE 9 中已被标记为过时,并声明将在未来的版本中移除。
动机
-
这些技术获得了与 Java SE 无关的功能。例如,Common Annotations 在 Java EE 6 中添加了一个与 Java EE 容器中的数据源有关的包。这就使得有必要定期对 Java EE 版本进行快照并创建子集,这对 JDK 工程师来说非常耗时,也让开发人员感到困惑。
-
这些技术由 java.net 上游项目维护,后来又在 GitHub 上进行维护。由于必须将 OpenJDK 代码库中的 Java SE 版本与上游代码库中的 Java EE 版本同步,因此维护起来存在问题。
-
开发人员可以从上游项目获取这些技术的独立版本,并通过认可标准覆盖机制进行部署。这种长期存在的机制允许独立版本安全地覆盖 Java SE 版本。但不幸的是,该机制在实践中并未得到广泛使用,开发人员反而使用特设机制来部署独立版本,例如将它们预先添加到 JDK 的引导类路径中,或者简单地将它们放在类路径上,寄希望于生成的拆分包不会引发问题。
由于 Java EE 技术的独立版本可以从第三方站点(如 Maven Central)轻松获取,因此 Java SE 平台或 JDK 无需包含它们。
-
由于 CORBA 是一个在 Java 社区流程之外演进的“认可标准”,因此与 Web 服务类似的评论也适用于 JDK 中 CORBA 的维护,以及安全覆盖 JDK 的 CORBA 实现的能力。在 JDK 中的 ORB 与 Java EE 应用服务器中的 ORB 同步没有任何现实的前景。
-
在 Java 中使用 CORBA 开发现代应用程序没有显著的兴趣。此外,Java EE 8 将 CORBA、RMI-IIOP 和 JavaIDL 列为“建议可选项”,这表明对这些技术的必要支持可能会在未来被取消。
由于维护 CORBA 支持的成本超过了收益,因此 Java SE 平台或 JDK 没有理由包含它。
最后,自 Java SE 1.3 以来,Java SE 包含了 JTA(Java 事务 API)的一个子集,而自 Java SE 5.0 以来,包含了 J2EE Activity Service for Extended Transactions(J2EE 活动服务)的一个子集。
JTA 包含两个扮演不同角色且需要不同处理的包:
-
javax.transaction.xa
包支持 JDBC 中的 XA 事务。这个 “XA 包” 在 Java SE 9 中与 JDBC 一起位于java.sql
模块中。由于java.sql
模块不可升级,因此独立版本的 JTA 无法覆盖 Java SE 版本的 XA 包,但这通常对应用程序是可以接受的,因为 XA 包多年来一直保持稳定,并且 Java SE 版本与 Java EE 版本相同。为了便于维护,Java SE 中的 XA 包将来可能会移动到另一个不可升级的模块中,但从架构的角度来看,它将长期与 JDBC 一起保留在 Java SE 中,对于此 JEP 来说不再具有进一步的关注价值。 -
javax.transaction
包定义了一个通用的事务管理 API。该包的 Java EE 版本始终超出 Java SE 的范围,并以与 Java SE 无关的方式进行了演变。例如,JTA 在 Java EE 7 中添加了与 CDI 相关的类型。由 Java SE 定义的javax.transaction
子集支持与 CORBA 事务服务的互操作。这个 “CORBA 互操作包” 在 Java SE 9 中存在于其自己的java.transaction
模块中。然而,Java SE 版本通常不被使用 CORBA 事务服务的应用程序所接受,因此它们通常会用 Java EE 版本来覆盖它。
J2EE 活动服务定义了一个通用的中间件 API。自 2006 年以来,它一直没有更新,并且不是 Java EE 平台的一部分。它与本 JEP 的相关性仅在于 Java SE 包含了其一个包 javax.activity
的子集,用于与 CORBA 事务服务进行互操作。这个“活动包”存在于 Java SE 9 的 java.corba
模块中。
在 Java SE 平台或 JDK 中没有 CORBA 支持的情况下,没有理由包含来自 JTA 的 CORBA 互操作包或来自 J2EE Activity Service 的 activity 包。
描述
在 Java SE 9 中,包含 Java EE 和 CORBA 技术的 Java SE 模块被标注为计划移除的已弃用功能,这表明了在未来的版本中将移除这些模块的意图:
Java SE 9 中的相关模块也已被弃用以便删除:
java.se.ee
(上述六个模块的聚合器模块)jdk.xml.ws
(JAX-WS 的工具)jdk.xml.bind
(JAXB 的工具)
由于弃用模块以进行移除仅仅会导致编译时警告,JDK 9 采取了更为强有力的步骤,以让开发者为这些模块在将来版本中的实际移除做好准备:在类路径上编译或运行代码时,JDK 运行时镜像中的模块未被解析。这使得使用 JDK 9 的开发者能够在类路径上部署 Java EE 和 CORBA 技术的独立版本,就像在 JDK 8 上一样。或者,使用 JDK 9 的开发者可以在命令行中使用 --add-modules
来解析 JDK 运行时镜像中的模块。
在 Java SE 11 中,上文列出的九个模块将被移除:
- 它们的源代码将从 OpenJDK 仓库中删除。
- 它们的类将不存在于 JDK 运行时镜像中。
- 它们的工具将不再可用:
wsgen
和wsimport
(来自jdk.xml.ws
)schemagen
和xjc
(来自jdk.xml.bind
)idlj
、orbd
、servertool
和tnamesrv
(来自java.corba
)
- JNDI
CosNaming
提供程序(来自java.corba
)将不再可用。 - 没有任何命令行标志能够启用它们,就像 JDK 9 中的
--add-modules
那样。
rmic
编译器将被更新以移除 -idl
和 -iiop
选项。因此,rmic
将不再能够生成 IDL 或 IIOP 存根和绑定类。
JDK 文档 和手册页将更新,以删除对这些模块和工具的引用,并指明 rmic
的变化。
测试
所有运行 Java EE 或 CORBA API 的 JDK、JCK 和 SQE 测试都将被移除。
风险与假设
Java EE 模块
移除 Java EE 模块的风险在于,如果应用程序依赖 JDK 中“开箱即用”的 Java EE API 和工具支持,它们将无法编译或运行。当这些应用程序从 JDK 6、7 或 8 迁移到 JDK 9 或更高版本时,将会遇到二进制和源码不兼容的问题。一般来说,这些应用程序可以分为以下两类:
-
独立的程序,位于 Java EE 应用服务器之外,用于操作 Web 服务和 XML。
-
与 Web 服务或 XML 无关,但依赖于 Java EE API 中的个别类来实现通用功能的应用程序。例如,某些应用程序依赖 JAXB 并非为了 XML 绑定,而是为了
javax.xml.bind.DatatypeConverter
类提供的 Base64 支持。(从历史上看,这个类比sun.misc.Base64{Encoder,Decoder}
是更好的选择,不过在 Java SE 8 中引入的java.util.Base64
类则是更好的选择。)再比如,有些应用程序依赖@Generated
注解,其类型javax.annotation.Generated
在 JDK 9 中与 JAX-WS 共存。(应用程序也可以选择依赖在 Java SE 9 中引入的javax.annotation.processing.Generated
类型。)
移除 Java EE 模块的另一个风险是,那些已经从 JDK 6、7 或 8 迁移到 JDK 9 的应用程序如果使用了命令行标志 --add-modules java.se.ee
、--add-modules java.xml.bind
等,将无法启动。
该提案假定希望在最新的 JDK 上编译或运行应用程序的开发人员可以找到并部署 Java EE 技术的替代版本。JAX-WS 和 JAXB 的参考实现 (RIs) 是一个好的起点,因为它们是 JDK 9 中 java.xml.ws
和 java.xml.bind
模块的完整替代品。这些 RIs 可作为 Maven 构件获取:(注意,它们必须部署在类路径上)。
- com.sun.xml.ws : jaxws-ri (JAX-WS,加上 SAAJ 和 Web 服务元数据)
- com.sun.xml.bind : jaxb-ri (JAXB)
JAX-WS 和 JAXB 的工具也可以作为 Maven 工件使用:
wsgen
和wsimport
: com.sun.xml.ws : jaxws-tools,以及 工具脚本schemagen
和xjc
: com.sun.xml.bind : jaxb-jxc 和 com.sun.xml.bind : jaxb-xjc,以及 工具脚本
还有一些 Maven 工件,其中仅包含 Java EE 技术的 API:
- javax.xml.ws : jaxws-api(JAX-WS,加上 javax.xml.soap : javax.xml.soap-api 用于 SAAJ 和 javax.xml : webservices-api 用于 Web 服务元数据)
- javax.xml.bind : jaxb-api(JAXB)
- javax.activation : javax.activation-api(JAF)
- javax.annotation : javax.annotation-api(通用注解)
在此 JEP 实施后,这些 API 的 JAR 文件可以部署在类路径上,就像在 JDK 8 和 JDK 9 上一样。它们也可以部署在模块路径上,以便模块化应用程序可以通过 requires
指令依赖它们:
-
JAX-WS、JAXB 和 SAAJ 的 API JAR 文件是名为
java.xml.ws
、java.xml.bind
和java.xml.soap
的显式模块。 -
Web Services Metadata 的 API JAR 文件是一个名为
webservices.api
的自动模块。(此名称是从 JAR 文件名派生的,因为 JAR 清单尚未使用Automatic-Module-Name
属性进行更新。) -
JAF 和 Common Annotations 的 API JAR 文件是名为
java.activation
和java.annotation
的自动模块。(这些名称由 JAR 清单中的Automatic-Module-Name
属性指定。)
在 JDK 9 中,描述中提到的所有模块(java.se.ee
聚合器除外)都是可升级的。这意味着使用 --add-modules java.xml.bind
等选项的 JDK 9 开发人员可以选择依赖 JDK 运行时镜像中的 Java EE 模块,或者通过在升级模块路径上部署 API JAR 文件来覆盖它们。请注意,这里涉及的是升级模块路径,而不是模块路径;在 JDK 9 的模块路径上部署 API JAR 文件不会产生任何效果,即使使用了 --add-modules java.xml.bind
等选项,因为 JDK 运行时镜像中的 Java EE 模块优先于模块路径上同名的模块。在此 JEP 实施后,Java EE 模块将不再存在于 JDK 运行时镜像中,因此开发人员可以在模块路径上部署 API JAR 文件。
CORBA 和 JTA 模块
移除 java.corba
模块的风险包括:
-
如果 CORBA 实现仅包含部分 "认可的" CORBA API,并期望 JDK 提供其余部分,则这些实现将无法编译或运行。
-
使用 RMI-IIOP 的应用程序和 CORBA 实现将无法编译或运行。RMI-IIOP 包(
javax.rmi
和javax.rmi.CORBA
)位于java.corba
模块中,并与其中的 CORBA 实现绑定,因此一旦移除java.corba
,Java SE 中将不再支持 RMI-IIOP。 -
使用
javax.activity
包的应用程序和 CORBA 实现将无法编译或运行。该包位于java.corba
模块中,并与其中的 CORBA 实现绑定,因此一旦移除java.corba
,Java SE 中将不再提供支持。
除非第三方接手 CORBA API、ORB 实现、CosNaming 提供者等的维护工作,否则将不会有单独版本的 CORBA。第三方维护是可能的,因为 Java SE 平台支持 CORBA 的独立实现。相比之下,RMI-IIOP 的 API 仅在 Java SE 内定义和实现。除非启动专门的 JSR 来维护它,或者 API 的管理权被 Eclipse 基金会接管,否则将不会有单独版本的 RMI-IIOP。Java EE 从 JCP 到 Eclipse 基金会的管理权过渡包括 CORBA 和 RMI-IIOP 的 GlassFish 实现。最后,J2EE Activity Service 没有单独版本。
JTA 的独立版本作为 Maven 工件 javax.transaction : javax.transaction-api 提供。截至 2017 年 11 月,此 JAR 文件代表 JTA 1.2,包含 XA 包和 CORBA 互操作包。在 2018 年初,JTA 1.3 将被定义为仅包含 CORBA 互操作包;JAR 文件将相应更新。JTA 1.2 和 JTA 1.3 的 JAR 文件可以如下部署:
-
JTA 1.2 的 JAR 文件可以部署在类路径上。(JAR 文件中的 XA 包会被忽略,而优先使用
java.sql
模块中的 XA 包。JAR 文件中的 CORBA 互操作包会优先于java.transaction
模块中的包,后者在 JDK 9 中默认未解析。需要注意的是,如果在 JDK 9 中使用了--add-modules java.se.ee
或--add-modules java.transaction
,那么 JAR 文件中的 CORBA 互操作包将被忽略,而优先使用java.transaction
模块中的包。) -
JTA 1.2 的 JAR 文件可能无法部署在模块路径上。(它会被视为一个包含 XA 包的自动模块,但这个包会与
java.sql
模块中的 XA 包发生冲突。) -
JTA 1.3 的 JAR 文件可以部署在类路径上。(JAR 文件中的 CORBA 互操作包会优先于
java.transaction
模块中的包,后者在 JDK 9 中默认未解析。) -
JTA 1.3 的 JAR 文件可以部署在模块路径上,并用作名为
java.transaction
的自动模块。