Semantic versioning (was: NP-Completeness...)

Jesse Glick jesse.glick at oracle.com
Fri Dec 23 06:33:09 PST 2011


On 12/23/2011 03:35 AM, Peter Kriens wrote:
> With an API you have a consumer of an API and a provider of that API [...]
> few people get the implications of APIs based programming and semantic versioning.

I guess you are referring to semver [1]. I agree that, while well-intentioned, that system does not adequately deal with modules which expose both a widely-used API and 
an SPI with a few implementations, or (more generally) multiple categories of interface intended for different clients with varying tolerance for incompatibility. If all 
these interfaces are presented indiscriminately as the "exports" of a versioned module, you get into a catch-22 when trying to introduce an incompatible SPI change while 
keeping the API fully compatible (or, generally, changing only those interfaces with a few well-known clients): you must mark the module version incompatible, to ensure 
that SPI implementors are updated to match the changes; but if you do so then the universe of API users will be gratuitously shut out of what would otherwise be a simple 
upgrade.

An unsatisfactory resolution is to version all SPI changes like compatible API changes, and just hope for the best. This seems to have been the policy of Java SE, with 
the result that the occasional implementor of DOM or JDBC interfaces (proxies, unit test mocks, ...) routinely becomes uncompilable with a new JDK (*). Such a policy 
becomes intolerable when pieces of the platform are downloaded according to version constraints.

Another resolution is to separate the SPI into its own package structure (as is common anyway) and version individual packages, as might be done in OSGi bundles. This is 
impossible in the current design of Jigsaw, of course, or generally in any module system aspiring to have a 1-1 mapping between module versions (and dependencies) and 
native package versions (resp. dependencies).

An arguably simpler resolution is to use a single module version but treat the semantics of its dotted components differently depending on the category of import. The 
OSGi "Semantic Versioning" section (3.7.3 in r4 4.3) advocates this, though it assumes that _any_ change to the SPI is automatically incompatible which seems overly 
pessimistic. The Jigsaw draft does not offer any real advice on version policy, or even describe exactly how version ranges may be expressed, but it seems to support 
(manual and unenforced) use of this policy. (**) In my draft proposal for updated versioning policy in the NetBeans module system [2] I take this approach, with the added 
twist of using the build system to enforce the correct kind of version range for an importer based upon its actual imports (under the condition that import categories map 
to package boundaries).


(*) Yes I have seen the proposal for interfaces with default method bodies in JDK 8. This provides a workaround for one class of incompatible changes - adding interface 
methods. Conscientious SPI designers could already avoid the problem in various ways, such as optional extension interfaces or abstract classes, but obviously many chose 
not to. (Nor are incompatible changes limited to this, of course - you may want a static factory method to take a list of something rather than a single object, ad 
nauseam.) I would urge the JLS [3] to be amended to say that adding an interface method (without a proposed default body) _does_ break binary compatibility, and be 
treated accordingly for purposes of versioning.

(**) For better or worse, Jigsaw also supports "permits" clauses by which only enumerated friend modules could use the SPI. The NetBeans module system has had a similar 
feature since 2005 but it has proven unworkable, and my proposal [2] essentially deprecates it. My understanding is that Eclipse continues to declare "friends", via 
package import constraints with partial tool enforcement.


[1] http://semver.org/
[2] http://wiki.netbeans.org/NbmPackageStability#Marking_stability_of_import
[3] http://java.sun.com/docs/books/jls/third_edition/html/binaryComp.html#13.5.3



More information about the jigsaw-dev mailing list