JEP 322:基于时间的发布版本控制
概括
针对当前和未来基于时间的发布模型,修改 Java SE 平台和 JDK 的版本字符串方案以及相关版本控制信息。
目标
-
重新设计JEP 223引入的版本号方案,使其更好地适合基于时间的发布模型,该模型定义了可以包含新功能的_功能版本_和仅修复错误的_更新版本。_
-
允许使用当前模型以外的基于时间的发布模型,具有不同的节奏或具有小于功能版本但大于更新版本的_临时版本。_
-
保持与整体 JEP 223 版本字符串方案的兼容性。
-
让开发人员或最终用户轻松了解版本的历史,以便他们可以判断是否将其升级到具有最新安全修复程序和可能的附加功能的新版本。
-
为实现者提供一种方法来表明某个版本是该实现者提供长期支持的一系列版本的一部分。
-
为实现者提供一种方法来包含和显示附加的、特定于实现者的版本字符串,以便使版本与相关产品保持一致。
非目标
修改现有版本字符串方案以适应与基于时间的发布模型相关的需求之外的需求并不是我们的目标。
修改除启动器之外的命令行工具的版本报告输出不是目标java
。这样做是可取的,但并不重要,并且可以稍后完成。
动机
JEP 223引入的版本字符串方案比过去有了重大改进。然而,该方案不太适合未来,我们打算严格按照六个月的节奏发布 Java SE 平台和 JDK 的新版本。
JEP 223 方案的主要困难在于,发行版的版本号编码了其相对于其前身的重要性和兼容性。然而,在基于时间的发布模型中,这些品质是无法提前得知的。它们在整个版本的开发周期中可能会发生变化,直到集成最终功能。因此,发布的版本号也是事先无法得知的。
根据 JEP 223 的版本号语义,每个开发 JDK 版本的人,或者在其之上构建或使用组件的人,都必须首先谈论该版本的发布日期,然后在发布后转而谈论版本号。是已知的。维护库、框架和工具的开发人员必须准备好更改在每个 JDK 发布周期后期检查版本号的代码。这对所有参与者来说都是尴尬和困惑的。
因此,这里提出的主要更改是重新设计版本号,以编码不是兼容性和重要性,而是编码发布周期方面的时间流逝。这更适合基于时间的发布模 型,因为每个发布周期以及每个发布的版本号始终是提前已知的。
描述
版本号
_版本号_是由$VNUM
句点字符 (U+002E) 分隔的非空元素序列。元素要么为零,要么是不带前导零的无符号整数。版本号的最后一个元素不能为零。当一个元素增加时,所有后续元素都会被删除。格式为:
[1-9][0-9]*((\.0)*\.[1-9][0-9]*)*
该序列可以是任意长度,但前四个元素被赋予特定含义,如下所示:
$FEATURE.$INTERIM.$UPDATE.$PATCH
-
$FEATURE
— 功能发布计数器,无论发布内容如何,都会针对每个功能发布而递增。可以在功能发布中添加功能;如果提前通知至少一项功能发布,它们也可能被删除。合理时可以进行不兼容的更改。 (以前$MAJOR
。) -
$INTERIM
— 临时版本计数器,对于包含兼容的错误修复和增强功能但没有不兼容的更改、没有功能删除以及没有对标准 API 进行更改的非功能版本递增。 (以前$MINOR
。) -
$UPDATE
— 更新版本计数器,针对修复新功能中的安全问题、回归和错误的兼容更新版本而递增。 (以前是$SECURITY
,但具有重要的增量规则。) -
$PATCH
— 紧急补丁发布计数器,仅在需要生成紧急版本来解决关键问题时才会增加。 (为此目的使用附加元素可以最大限度地减少对正在进行的更新版本的开发人员和用户的干扰。)
版本号的第五个及后面的元素保留供 JDK 代码库的下游使用者使用。第五元素可以用于_例如_识别特定于实现者的补丁版本。
版本号永远不会有尾随零元素。如果一个元素及其后面的所有元素逻辑上的值为零,则所有元素都将被忽略。
版本号中的数字序列以数字、逐点的方式与另一个此类序列进行比较;例如,10.0.4
小于10.1.2
。如果一个序列比另一个序列短,则较短序列的缺失元素被认为小于较长序列的相应元素;例如,10.0.2
小于10.0.2.1
。
六个月发布模型中的版本号
在六个月发布模型下,版本号的元素变化如下:
-
$FEATURE
每六个月递增:2018 年 3 月发行版是 JDK 10,2018 年 9 月发行版是 JDK 11,依此类推。 -
$INTERIM
始终为零,因为六个月模型不包括临时版本。我们在这里保留它是为了灵活性,以便将来版本模型的修订可以包括此类版本,并说 JDK$N.1
和 JDK$N.2
是 JDK 的兼容升级$N
。例如,JDK 1.4.1 和 1.4.2 版本本质上是临时版本,在此方案下编号为 4.1 和 4.2。 -
$UPDATE
递增一个月后递增$FEATURE
,此后每三个月递增:2018 年 4 月版本是 JDK 10.0.1,7 月版本是 JDK 10.0.2,依此类推。
我们确实希望大多数功能版本至少包含一两个重要功能,并且更新版本永远不会包含不兼容的更改。 结合$INTERIM
始终为零的事实,在实践中,该方案通常会定义与 JEP 223 方案定义的版本号没有太大区别的版本号。
版本字符串
版本字符串的整体格式与JEP 223中定义的相同。版本字符串是版本号 ,$VNUM
后面可能跟有预发布、构建和其他可选信息,其中之一是:
$VNUM(-$PRE)?\+$BUILD(-$OPT)?
$VNUM-$PRE(-$OPT)?
$VNUM(+-$OPT)?
其中$PRE
是预发布标识符(例如ea
),$BUILD
是内部版本号,$OPT
是可选的内部版本信息。
如果某个版本是实施者提供长期支持的一系列版本的一部分,则 的值$OPT
应以 开头"LTS"
,例如 11.0.2+13-LTS。这将导致在_等_"LTS"
的输出中突出显示java --version
,下面将详细介绍。
应用程序编程接口
我们对 JEP 223 定义的Runtime.Version
API进行了如下修改:
-
int
为上面定义的版本号的主要组成部分添加四个新的返回访问器方法:feature()
、interim()
、update()
和patch()
。 -
重新定义现有访问器方法
major()
、minor()
和 ,以分别返回与、和security()
相同的值。feature()``interim()``update()
-
弃用现有的访问器方法,但不删除,建议使用相应的新方法。这将有助于开发人员清楚版本号的新语义。
系统属性
对于JEP 223中提到的系统属性,我们添加了两个新属性:
java.version.date
— 此版本的正式发布 (GA) 日期,采用 ISO-8601 YYYY-MM-DD 格式。对于早期访问版本,这将是预期的 GA 日期,_即_未来的某个日期。
这个新属性可以很容易地 计算出版本的发布时间,这样作为用户,您就可以了解自己落后了多远。它还反映了版本的安全级别:如果给定的 GA 版本的版本日期不早于任何其他 GA 版本,则该版本包含最新的安全修复程序。
java.vendor.version
— 特定于实现者的产品版本字符串,可以选择由生成特定实现的个人或组织分配。如果在构建时没有分配,那么它没有价值;否则,其值为与正则表达式匹配的非空字符串\p{Graph}+
。
这个新属性使实现者可以提供与相关产品保持一致所需的附加版本信息。产品线使用_例如_表单的基于日期的版本的实现者$YEAR.$MONTH
可以相应地设置该属性,以便他们的JDK版本与他们的其他版本明显相关。 (此属性被命名java.vendor.version
而不是更明显,java.implementor.version
以便与名称包含的现有系统属性vendor
保持一致。)
启动器
java
对于假设的 JDK 10.0.1 版本 13,启动器将显示版本字符串和系统属性,如下所示:
$ java --version
openjdk 10.0.1 2018-04-19
OpenJDK Runtime Environment (build 10.0.1+13)
OpenJDK 64-Bit Server VM (build 10.0.1+13, mixed mode)
$
同样,对于 JDK 11 的假设构建 42,LTS 版本:
$ java --version
openjdk 11 2018-09-20 LTS
OpenJDK Runtime Environment (build 11+42-LTS)
OpenJDK 64-Bit Server VM (build 11+42-LTS, mixed mode)
$
如果实现者将供应商版本字符串(例如)分配18.9
给 JDK 11 LTS 版本,则将显示:
$ java --version
openjdk 11 2018-09-20 LTS
OpenJDK Runtime Environment 18.9 (build 11+42-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11+42-LTS, mixed mode)
$
具体来说,启动器的版本报告选项的输出java
将采用如下格式,其中如果前三个字符是,则${LTS}
扩展为,如果定义了该系统属性,则扩展为:"\u0020LTS"``$OPT``"LTS"``${JVV}``"\u0020${java.vendor.version}"
$ java --version
openjdk ${java.version} ${java.version.date}${LTS}
${java.runtime.name}${JVV} (build ${java.runtime.version})
${java.vm.name}${JVV} (build ${java.vm.version}, ${java.vm.info})
$
$ java --show-version < ... >
openjdk ${java.version} ${java.version.date}${LTS}
${java.runtime.name}${JVV} (build ${java.runtime.version})
${java.vm.name}${JVV} (build ${java.vm.version}, ${java.vm.info})
[ ... ]
$
$ java --full-version
openjdk ${java.runtime.version}
$
$ java -version
openjdk version \"${java.version}\" ${java.version.date}${LTS}
${java.runtime.name}${JVV} (build ${java.runtime.version})
${java.vm.name}${JVV} (build ${java.vm.version}, ${java.vm.info})
$
$ java -showversion < ... >
openjdk version \"${java.version}\" ${java.version.date}${LTS}
${java.runtime.name}${JVV} (build ${java.runtime.version})
${java.vm.name}${JVV} (build ${java.vm.version}, ${java.vm.info})
[ ... ]
$
$ java -fullversion
openjdk full version \"${java.runtime.version}\"
$
@since
JavaDoc 标签
JavaDoc 标记使用的值@since
继续与系统属性保持一致java.specification.version
,因此 JDK 10 中引入的 API 将被标记@since 10
。
Mercurial 变更集标签
标识升级版本的 Mercurial 标签的通用语法没有改变:jdk\-$VNUM\+$BUILD
。
构建配置和输出
三个现有的与版本相关的配置选项将被弃用并被忽略,并且相关的 Make 变量将不再被定义:
--with-version-major VERSION_MAJOR
--with-version-minor VERSION_MINOR
--with-version-security VERSION_SECURITY
将定义五个新选项和相应的变量:
--with-version-feature VERSION_FEATURE
--with-version-interim VERSION_INTERIM
--with-version-update VERSION_UPDATE
--with-version-date VERSION_DATE
--with-vendor-version-string VENDOR_VERSION_STRING
(不需要定义--with-version-patch
和VERSION_PATCH
,因为它们已经存在。)
写入 JDK 映像根目录的文件release
除了定义现有JAVA_VERSION
变量之外,还会定义系统属性JAVA_VERSION_DATE
的值java.version.date
以及系统属性IMPLEMENTOR_VERSION
的值java.vendor.version
(如果已定义)。
备择方案
基于六个月时间的发布模型的提案建议功能发布的版本字符串采用以下形式$YEAR.$MONTH
。因此,明年 3 月份的版本将为 18.3,9 月份的版本将为 18.9,依此类推。
在对该方案提出合理的反对意见后,我们审查了版本号中编码的各种类型的信息并提出了一些替代方案,然后对随后的讨论进行了总结和回应,最后发表了一个受到好评的提案,因此成为了此方案的基础。杰普。
测试
这个较新的版本字符串方案在很大程度上与JEP 223定义的方案兼容,因此测试应该很简单。主要区别是第四个元素可能用于紧急补丁发布,这可能需要一些新的单元测试用例。对相关构建配置选项的更改将需要简单的手动测试。
风险和假设
此处描述的更改引入了三个轻微的不兼容性:
-
JEP 223指定了API 返回版本号元素值的
security()
方法。当它前面的元素 ,递增时,该元素不会递增。该提案将该元素重命名为 ,并在其前面的元素(以前的)增加时清除该元素。因此,从理论上讲,重新定义“in”是一种不相容的变化。然而,此 API 是在 JDK 9 中引入的,并且预计不会有非零值的 JDK 9 版本,因此在实践中,此更改应该产生最小的影响。Runtime.Version``$SECURITY``$MINOR``$SECURITY``$UPDATE``$INTERIM``$MINOR``security()``update()``$MINOR
-
启动器版本报告选项的输出
java
现在包括第一行末尾的版本日期,后面可能跟着"\u0020LTS"
.在假设行上的最后一个标记是版本号的情况下解析此输出的现有代码可能需要调整。 -
java
启动器的--version
、--show-version
、-version
和选项的输出-showversion
将在第二行和第三行包含系统属性的值java.vendor.version
(如果该值与java.version
.解析此输出的现有代码可能需要调整。