Alex headshot

AlBlue’s Blog

Macs, Modularity and More

Using Humans to solve a Tooling problem

2012 Osgi Eclipse

I’ve just written up a piece at InfoQ on how OSGi have abandoned -SNAPSHOT versions, and I thought I’d take a minute to explain what I meant by the ‘human tooling’ problem.

The issue is whether or not SNAPSHOTs shold be built in a ‘lower’ numerical namespace using 1.2.3-456 which sorts less than 1.2.3. By encouraging a difference between ‘unreleased’ and ‘released’ versions, it becomes clear whether there are changes which are important, and allows developers to report bugs against a specific version (instead of just ‘the latest version’).

According to both the Semantic Versioning and the Eclipse Version Numbering rules, the patch number (third segment) should be changed whenever there is a difference between build artefacts. As I’ve listed on the InfoQ article, that plainly doesn’t happen in some cases:

  • org.eclipse.cdt.codan.checkers.ui_1.0.0.201109151620.jar
  • org.eclipse.cdt.codan.checkers.ui_1.0.0.201202111925.jar
  • org.eclipse.core.filebuffers_3.5.200.v20110505-0800.jar
  • org.eclipse.core.filebuffers_3.5.200.v20110928-1504.jar
  • org.eclipse.core.variables_3.2.500.v20110511.jar
  • org.eclipse.core.variables_3.2.500.v20110928-1503.jar
  • org.eclipse.emf.ecore_2.7.0.v20110912-0920.jar
  • org.eclipse.emf.ecore_2.7.0.v20120127-1122.jar
  • org.eclipse.equinox.frameworkadmin.equinox_1.0.300.v20110506.jar
  • org.eclipse.equinox.frameworkadmin.equinox_1.0.300.v20110815-1438.jar
  • org.eclipse.equinox.p2.updatesite_1.0.300.v20110510.jar
  • org.eclipse.equinox.p2.updatesite_1.0.300.v20110815-1419.jar
  • org.eclipse.jdt.compiler.tool_1.0.100.v_B76_R37x.jar
  • org.eclipse.jdt.compiler.tool_1.0.100.v_B79_R37x.jar
  • org.eclipse.jface_3.7.0.I20110522-1430.jar
  • org.eclipse.jface_3.7.0.v20110928-1505.jar
  • org.eclipse.ltk.core.refactoring_3.5.201.r371_v20110824-0800.jar
  • org.eclipse.ltk.core.refactoring_3.5.201.r372_v20111101-0700.jar
  • org.eclipse.pde.runtime_3.4.201.v20110819-0851.jar
  • org.eclipse.pde.runtime_3.4.201.v20110928-1516.jar
  • org.eclipse.ui_3.7.0.I20110602-0100.jar
  • org.eclipse.ui_3.7.0.v20110928-1505.jar

The point of showing the cross-section of the above is not to highlight specific projects, but to show this is a widespread problem that goes across all projects. The problem is, there is no ‘penalty’ for leaving a 1.2.3.qualifier as the Manifest entry and just spinning out builds with new build qualifiers in place.

The key advantage of having a different version numbering format between release versions and pre-release versions is to ensure that at release, the version number is updated appropriately. This means that the development process generally follows:

  • Create 1.0.0-SNAPSHOT for development
  • Do work
  • Release 1.0.0
  • Update version to 1.0.1-SNAPSHOT
  • Do work
  • Release 1.0.1 or 1.1.0 (or 2.0.0) as appropriate
  • goto 10

The decision as to what to call the next number can either be tracked by updates to the -SNAPSHOT itself (e.g. moving to 1.1.0-SNAPSHOT) or can be deferred to later in the process. There’s even tooling to help you do that (the mvn release plugin) – though this just removes the -SNAPSHOTS for you rather than doing any semantic analysis.

This pattern is so common that it’s even codified as a bullet point in the Semantic Versioning specification:

A pre-release version MAY be denoted by appending a dash and a series of dot separated identifiers immediately following the patch version. Identifiers MUST be comprised of only ASCII alphanumerics and dash [0-9A-Za-z-]. Pre-release versions satisfy but have a lower precedence than the associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.

The ‘pre-release versions satisfy but have a lower precedence than’ sums up the rule in a nutshell: in other words, anywhere a 1.2.3 is valid then all 1.2.3-* are valid as well; anywhere a 1.2.3 is not valid then all 1.2.3-* are not valid. So, in a range like [1.2.3,4.5.6) then any pre-release state of 1.2.3-* is included, but any pre-release state of 4.5.6-* is not included.

This was even implemented successfully in Equinox, with an implementation in 3.8M6.

Unfortunately, the concerns listed by the CPEG were out of touch with how developers work outside of the OSGi space, and instead of reaching out with a mechanism which would have been compatible for released artifacts (whilst providing a SNAPSHOT style build system that would not be loadable on older OSGi runtimes) it has been removed from the specification. Given that OSGi R5 is a major release of the runtime, this would have been the ideal time for introducing a new version syntax, and one that would have been quickly adopted elsewhere.

So instead of having ‘memorable’ artifact names like org.eclipse.ui_3.7.0.jar we’ll be stuck with unmemorable names like org.eclipse.ui_3.7.0.v20110928-1505.jar for the forseeable future in the OSGi world. This causes more cognitive work for humans (trying to remember the name) whilst introducing more opportunity for mistakes (by releasing the same major/minor/patch with different builds).

This is what I refer to as humans solving the tooling problem, rather than the other way around.