JDK Release Types and Compatibility Regions
By darcy on Aug 17, 2009
There are three primary kinds of compatibility of concern when evolving the JDK, source, binary, and behavioral. These can be visualized as defining a three dimensional space:
The farther away a point is from the origin, the more incompatible a change is; the origin itself represents perfect compatibility (no changes). A more nuanced diagram would separate positive and negative compatibility, that is distinguish between keeping things that work working versus keeping things that don't work not working, but in this article the diagrams will just represent the magnitude of allowable compatibility change.
In turn, there are three main kinds of JDK releases:
JDK 7 is a platform release since it is a new version of platform; there are many new APIs added and thousands of bug fixes and enhancements. The JDK 6 update releases are representative of update releases; the same platform specification is implemented, Java SE 6 in this case, and there are typically dozens to a few hundred bug fixes and enhancements in a release (6 update train release notes). Like update releases, maintenance releases implement the same base specification as a previous platform release, such as JDK 1.4.1 and JDK 1.4.2 both being additional implementations of J2SE 1.4, but they have more bug fixes than an update release, on the order of one thousand to two thousand changes (JDK 1.4.2 release notes). While maintenance releases have not been formally issued since JDK 1.4.2, the changes in 6u10 were more on par with a maintenance release rather than a regular update release.
The general evolution policy for APIs in the JDK is:
Don't break binary compatibility (as defined in the Java Language Specification)
Avoid introducing source incompatibilities
Manage behavioral compatibility change
While these policies hold for all three kinds of releases, the allowable compatibility regions differ for kind of release. For update and maintenance releases, the reference point to measure compatibility against is an earlier implementation of the same platform specification, such as the initial reference implementation of the platform or an earlier update release.
Since binary incompatible changes are not allowed, the acceptable compatibility region for update and maintenance releases is confined to the (Behavioral × Source) plane, with more latitude on the behavioral axis. For update releases, a limited amount of behavioral change is acceptable, where behavioral change is broadly considered to be any observable aspect of the platform. While programs should only rely on specified interfaces, they can often accidentally rely on implementation details of the release's behavior so update releases limit the overall change in behavior. Some minor changes affecting source compatibly can occur in an update release, for example, the version of an endorsed standard or standalone technology included in the release can be upgraded. The JAX-WS component was upgraded from 2.0 to 2.1 in 6u4 (6535162). Such upgrades should generally preserve the meaning of existing programs that compile and possibly allow new programs to compile. The main compatibility effect should be that the negative compatibility region may get smaller; programs that "don't work" or "don't compile" can become programs that "work" or "compile." Maintenance release are generally similar, but more behavioral change is allowed and expected since there are a greater number of bug fixes and enhancements.
The compatibility reference point for a platform release is an implementation of the previous platform specification. Compared to the previous platform specification, a platform release can add APIs and language feature that impact source compatibility (new keywords, etc.) and the implementation can have many changes in behavior (such as changing the iteration order of
HashMap). In exceptional circumstances, there is the possibility of a sliver of binary incompatibility, such as to address a security issues in a rarely-used corner of the platform, but the central policy of preserving binary compatibility holds for platform releases as well.
Comparing one build of an in-progress platform release to another, there may be large changes in binary compatibility before a new API is finalized. As a matter of policy, certain kinds of source incompatibility will not be introduced into the platform anymore. For example, the Java language in JDK 7 will have no new keywords that invalidate existing sources; instead of a full new keyword, JSR 294 is making "
module" a restricted keyword whose use as a keyword versus an identifier will be disambiguated by the compiler.
Previously, there was a sharp jump down in the behavioral change allowed in a platform release compared to the first update of that new platform. A more helpful policy may be to allow greater behavioral change to new features in the first few updates of a new platform so that the implementation can be improved before widespread adoption justifies greater caution in managing behavioral change.