Version-string schemes for the Java SE Platform and the JDK (original) (raw)

mark.reinhold at oracle.com mark.reinhold at oracle.com
Thu Oct 19 15:08:36 UTC 2017


(This is a long note on a complex topic that's inherently difficult to discuss. If you wish to reply, please first read all the way through to the end.)

In my proposal to adopt a strict six-month release cadence I suggested that, going forward, the version strings of feature releases be of the form YEAR.YEAR.YEAR.MONTH [1][2]. Thus next year's March release would be 18.3, the September release would be 18.9, and so on each year.

Not everyone likes this proposal, which isn't surprising -- discussions of version-string schemes, much like those of language syntax, often tend to degenerate into bike-sheds [3][4]. That's due, in part, to the use of version strings -- across the software industry and for several decades now -- to encode multiple not-quite-orthogonal axes of information, which can answer different but often related questions:

Convention dictates that the principal part of a version string, i.e., the version number, be a sequence of numerals separated by period characters. (Let's ignore, for now, optional information such as pre-release status and build numbers.) Convention also dictates that version numbers be pointwise totally ordered, that they increase monotonically over time, and that the version number of a feature release be a prefix of the version numbers of its update releases.

Given these conventions and a strict, time-based release cadence, which of the above axes are both important and appropriate to encode into version numbers? Which are practical to encode into version numbers? Which should have more weight, i.e., be encoded in the earlier numerals of version numbers, and which should have less weight, i.e., be encoded in the later numerals?

Some considerations for each axis, in turn:

These considerations leave us with the final axis, time, as the leading candidate for the primary basis of Java SE and JDK version numbers.

This would be a departure from past releases, in which we've used version numbers that roughly encode both compatibility and significance. It is, however, a better fit for a strict, time-based release model since the version number of any particular release is known well in advance. The compatibility level of a release would still be indicated by the length of its version number, since we'll continue our long-standing practice of making obviously-incompatible changes only in feature releases. The security level of an update release would, similarly, be reflected in its version number as a whole, since a later release will always contain more security fixes than its predecessor.

The main remaining question, then, is that of how to encode time in version numbers: As an absolute value, derived from the date of the release, or as a relative value, measuring the amount of time since the previous release of the same type?

In the abstract, absolute times have three attractive properties:

Now, at last, for some concrete alternatives:

(A) Absolute: YYYYYYMM, padding the month number with a zero as needed, and YYYYYYMM.$AGE for update releases, where $AGE is the number of months since YYYYYYMM.

(B) Absolute: YY.YY.YY.M as proposed, without padding the month number, and YY.YY.YY.M.$AGE for update releases, where $AGE is as above.

(C) Relative: N,whereN, where N,whereN is the number of half-years since JDK 9 GA (September 2017) plus nine, and N.N.N.AGE for update releases, where AGEisasabove.(AGE is as above. (AGEisasabove.(AGE is more useful than another incrementing counter since it leaves room for emergency update releases without having to renumber subsequent update releases that are already in development.)

Examples of these alternatives, for the next two feature releases and their first two update releases:

                           (A)       (B)       (C)
GA (March 2018)            1803      18.3      10
First update (April)       1803.1    18.3.1    10.1
Second update (July)       1803.4    18.3.4    10.4
GA (September 2018)        1809      18.9      11
First update (October)     1809.1    18.9.1    11.1
Second update (January)    1809.4    18.9.4    11.4

Some pros (+) and cons (-) of each alternative (some of these points are subjective, but so it goes with this topic):

(A) YYYYYYMM, with YYYYYYMM.$AGE for updates

(+) Has the three advantages of absolute times.

(+) The `Runtime.Version` API introduced by JEP 223 can be adapted
    fairly easily.  Code that parses raw version strings would need
    little or no change (as long as it already does so correctly!).

(-) On the surface 1803 is an enormous leap from 9, is likely to
    cause confusion, and has connotations of being very old [8].

(B) YY.YY.YY.M, with YY.YY.YY.M.$AGE for updates

(+) Has the three advantages of absolute times.

(+) Similar to some other significant platforms, e.g., Ubuntu Linux,
    and less shocking in appearance than (A).

(-) People unfamiliar with the scheme could conflate 18.3 and 18.9 as
    being minor releases of JDK 18, which isn't the case.  There is
    some evidence of similar confusion around Ubuntu releases [9].

(-) The logical "major" version number is now a pair of numbers, year
    and month.  We could mitigate this in the `Runtime.Version` API
    by encoding the year and month as <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Y</mi><mi>Y</mi></mrow><annotation encoding="application/x-tex">YY</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">YY</span></span></span></span>MM in the existing major
    number, and adding new methods that return the year and month.
    Code that parses raw version strings will likely require change,
    including code not just in the JDK itself but in existing tools
    and CI systems [a].

(C) N,withN, with N,withN.$AGE for updates

(+) The most straightforward and least-surprising option, and
    familiar from other rapidly-evolving projects such as Firefox
    and Chrome.

(+) The `Runtime.Version` API can be adapted very easily, and code
    that (correctly) parses raw version strings would need no change.

(-) Lacks the three advantages of absolute times.

(-) If we ever switch to an even faster cadence then we could
    eventually have very large version numbers, as in (A).  In the
    limit we could wind up in a situation like that of CoreOS, whose
    latest stable release is numbered 1520.6 [b].

These are three plausible alternatives; there are countless others, but I suspect that many if not most are minor variants of these three. To mention just two examples:

If you've read this far, my question to you now is not the question that you might expect. Please don't say which version-number scheme you prefer for Java SE and the JDK. Instead, please only communicate any additional information that's relevant to the choice of such a scheme. In particular:

In order to discourage this from devolving into another version-numbering bike-shed discussion I'll give much greater weight to your first reply to this message than to any other, so please think and write carefully before you post. I'll also ignore replies-to-replies -- if you really want to argue with someone else about one scheme vs. another then I won't stop you, but I don't think that's a useful use of most readers' time. Finally, I'll heavily discount replies that quote more text from this message than add new text of their own, so please quote just the text that's actually needed to provide context for your reply.

In a week or so I'll summarize any new information received, and then make a specific proposal.

[1] https://mreinhold.org/blog/forward-faster [2] http://mail.openjdk.java.net/pipermail/discuss/2017-September/004281.html [3] http://bikeshed.org/ [4] https://wiki.haskell.org/Wadler's_Law [5] http://semver.org [6] http://openjdk.java.net/jeps/223 [7] https://mreinhold.org/blog/forward-faster#Proposal [8] https://en.wikipedia.org/wiki/1803 [9] http://mail.openjdk.java.net/pipermail/discuss/2017-September/004429.html [a] http://mail.openjdk.java.net/pipermail/discuss/2017-September/004352.html [b] https://coreos.com/releases



More information about the jdk-dev mailing list