Alex headshot

AlBlue’s Blog

Macs, Modularity and More

Components, products and fragile dependencies; JSR277 revisited

2008, eclipse, java, jsr277, osgi

My last post on JSR 277’s version number fiasco (which was cross-posted on DZone) discussed the futility of a version scheme used by almost no-one, but caused a number of comments to the effect that 4 version numbers being used by Oracle, Firefox, and of course Sun’s JDK.

This makes one very important error by association; all of those version numbers are products. That is Oracle is a product, Firefox is a product, the JDK is a product. None of them are components in the strict sense of the word; and whilst I’m sure someone is going to leave a comment saying “but you can embed Firefox”, that’s not the point either. Embedding a product into your app isn’t a component dependency using the same module system; there’s no OSGi “Firefox” bundle, and there’s no JSR277 “Firefox” module. So whilst XULRunner can be used, that’s a library which may not need to have the same versioning semantics as a product that contains it.

An example of product-versus-library is WebKit, the browser library that was first to release (although not first to claim) a build that fully passed the Acid3 test. The version that passed is generally referred to as r31326, since that’s the SVN trunk version that was used to compile and build the code. But (an older version of) this is embedded as part of Safari 3.1, and also other mobile device platorms (including, of course, the iPhone).

The point is that the versioning system of the underlying components can be completely different from the version number of a product-as-a-whole, which is (invariably) a collection of components underneath. One may have a user-friendly name (Leopard), a numerical version (10.5.3), a build tag (9D34) or indeed other ways of representing the install (/System/Library/Frameworks/System.framework/Versions/B). So arguing for a particular versioning scheme based on the versioning that may be used for marketing (or other) purposes is somewhat futile; both can co-exist and mean different things to different people. Eclipse learned the lesson in the 3.1 days, and since then, Eclipse 3.4 contains plugins like org.osgi.util_3.1.300 which are entirely distinct from their product name, since they haven’t changed other than bugfixes (i.e. no API or incompatible changes). Eclipse’s notes on Version numbering are recommended reading for anyone maintaining large systems. Indeed, Eclipse has moved away from version numbers for the product to use code-names like Europa and Ganymede.

Now let’s get back to the subject in hand. The JSR277 versioning is different from every other component model in deference to of a choice of product naming. Frankly, we know that the marketing names of each successive release of Java are going to change, so why pick a version system that’s known to be a failure already? In fact, in Stanley Ho’s rebuttal of my previous post, he states:

The JDK uses four numbers like 1.2.2_18 or 1.4.2_16 because of its longstanding practice that the major version is 1. You can argue whether this is good practice, but it’s the way the JDK is.

Indeed, the choice of product names of the JDK hasn’t ever been good. But it’s not like the JDK is being componentised into modules (like Harmony has) — it’s going to be One Big Blob. And let’s face it, if you’re writing Java code, you have to depend on the JDK anyway, so it’s not like it will be an optional dependency anywhere.

So, why not use three numbers to represent the version, and define that for JSR277 there’s a “1.” appended to the front? That seems like a reasonable choice, and follows Java’s lead. We could have a long-standing practice of depending on log4j, use commons-net, compile code with Antlr, and even use JSP to write Web 1.2.0 mashups. Alternatively, note that _18 and _16 are exactly the same length (and in the past have been prefixed by zeros, such as _01) so that they are equivalently comparable lexically as well as numerically.

It’s not just OSGi that JSR277 is ignoring. Maven is the default tool of choice for building large componentised applications in the open-source world; and whilst Ant is used widely, as the number of components grows the proportion of build systems swings strongly in Maven’s favour.