1. 引言

本文将深入探讨 Java 的时间驱动发布模式(Time-Based Releases)及其对各类开发者的影响。

Java 的发布节奏经历了重大调整,主要体现在新功能交付和支持周期的变化上。这些调整与 Oracle 自 2010 年以来支持的 Java 版本策略有明显不同。

2. 为什么是六个月发布周期?

对于习惯了 Java 历史上缓慢发布节奏的我们来说,六个月一次的发布节奏无疑是一次巨大转变。那么,为什么会有如此大的改变?

过去,Java 的重大版本通常围绕着一些大功能的引入来定义,这往往导致版本发布延迟,比如我们熟悉的 Java 8 和 9。此外,这种发布模式也拖慢了语言的演进速度,而像 NodeJS 和 Python 这样的语言则凭借更短的反馈周期迅速迭代。

简而言之,更短的发布周期意味着更小、更易管理的更新,也更容易被采纳。

这种模式在当前环境下非常契合,也让 JDK 的开发能够以敏捷的方式进行,与它所支持的社区保持一致。同时,也让 Java 在运行时生态中更具竞争力。

当然,慢节奏也有其优势,因此六个月的发布节奏也与长期支持(LTS)框架结合使用,详见第 4 节。

3. 版本号的变化

版本号的调整是这次发布策略变化中的一个重要机械性改变。

3.1. JEP 223 版本号格式

我们熟悉的旧版本号格式在 JEP 223 中被正式定义。该格式是递增的,并包含额外信息。

   实际版本                 假设展示
发布类型            完整版              简略版
------------           ------------------------ 
安全更新 2013/06       1.7.0_25-b15       7u25
小版本  2013/09       1.7.0_40-b43       7u40
安全更新 2013/10       1.7.0_45-b18       7u45
安全更新 2014/01       1.7.0_51-b13       7u51
小版本  2014/05       1.7.0_60-b19       7u60

如果我们在 Java 8 或更早版本的 JVM 上运行 java -version,会看到类似这样的输出:

>java -version
java version "1.6.0_27"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0_27-b07)
Java HotSpot(TM) Client VM (build 1.6.0_27-b13, mixed mode, sharing)

在这种情况下,我们可能会猜测这是 Java 6 的第 27 次更新 —— 但其实不是。这个编号系统并不像看起来那样直观。

小版本号通常是 10 的倍数,而安全更新填充其他数字。通常我们会看到本地安装的简略版本号,如 JDK 1.8u174。下一个小版本可能是 JDK 1.8u180,这是一个包含新修复的小版本。

3.2. 新版本号格式

新的版本号格式将“不再编码兼容性和重要性,而是编码时间的流逝,即发布周期”,Mark Reinhold 在 JEP 中如此解释

来看几个例子:

9.0.4
11.0.2
10.0.1

乍一看这很像 语义化版本控制(Semantic Versioning);❌ 但其实不是。

语义化版本的标准结构是 $MAJOR.$MINOR.$PATCH,而 Java 的新版本结构是:

$FEATURE.$INTERIM.$UPDATE.$PATCH

其中:

  • $FEATURE 相当于主版本号,但每六个月递增一次,无论是否向后兼容;
  • $PATCH 是维护版本;
  • $INTERIM 是占位符,目前始终为 0;
  • $UPDATE 是时间驱动的,每月更新一次。

此外,尾部的零会被省略。

这意味着:

  • 11 是 2018 年 9 月发布的 Java 11;
  • 11.0.1 是其 10 月的第一个月度更新;
  • 11.0.1.3 是该月度版本的第三个补丁版本(假设存在)。

4. 多版本分发策略

接下来我们来看看如何选择合适的 Java 版本。

4.1. 稳定性

简单来说,Java 现在有两个发布通道:快通道(每六个月)和慢通道(每三年)。每三年的版本被称为 LTS(长期支持)版本。

在快通道中,语言会发布处于孵化阶段的功能。这些功能在 LTS 版本中趋于稳定。

所以,如果公司愿意接受一定的不稳定性以换取新功能,可以选择快通道;而更注重稳定性的企业则可以等待 LTS 版本再升级。

开发者可以通过实验不同版本的 JDK 来找到最适合自己的版本。

4.2. 支持周期

当然,支持周期也是关键考量因素。现在 Java 8 已经不再被官方支持,我们应该怎么办?

如前所述,答案是 LTS 版本。目前最新的 LTS 是 Java 11,而下一个将是 Java 17。这些版本的更新由 Oracle、Azul 等厂商提供支持。

如果信任社区支持,Red Hat、IBM 等厂商也承诺为 OpenJDK 提供 bug 修复。此外,AdoptOpenJDK 项目也为 OpenJDK 提供预编译的二进制文件。

4.3. 授权许可

很多人对 OpenJDK 和 Oracle JDK 的区别感到困惑。

实际上,两者几乎完全相同,仅在 bug 修复和安全补丁方面略有差异,Brian Goetz 如是说

OpenJDK 是大多数衍生 JDK 的源头,且始终免费。 从 Java 11 开始,Oracle 对其 JDK 收取商业许可费用,但包含额外支持和服务。

4.4. 版本碎片化

随着发布频率提高,版本碎片化可能成为一个问题。理论上,不同团队可能运行在不同版本的 Java 上,拥有不同的功能支持。

当然,容器化技术可以缓解这一问题。从 Docker、CoreOS 到 Red Hat 的 OpenShift,容器化提供了必要的隔离性,不再强制整个服务器使用同一个 Java 安装路径。

5. 结论

总的来说,Oracle 的 Java 团队现在每六个月发布一次新版本,我们可以期待更多新功能的快速迭代。

作为 Java 开发者,每半年就能用上新语言特性,这无疑令人兴奋。

在选择升级通道时,我们需要考虑支持、授权和碎片化等问题,做出最适合自己项目的决策。


原始标题:Java's Time-Based Releases | Baeldung