OSGi Abandons Snapshot Proposal
With the recently-released OSGi Release 5 early access documents, one of the most anticipated features of the upcoming specification – that of SNAPSHOT style versions for OSGi – has been dropped from the specification because of concerns with existing tooling:
But the big concern come around interactions with existing tooling, management and provisioning systems. These systems would not understand a bundle having a pre-release version string. They would require a lot of changes to properly handle support the pre-release version syntax.
The problem stems from the differences between the way that Maven (and thus, Maven-compatible resolvers/build systems such as Ivy and Gradle) and the way that OSGi handle the empty qualifier are reversed. In Maven,
126.96.36.1992 <= 1.2.3, but in OSGi,
188.8.131.522 >= 1.2.3.
This causes problems when building components which are able to work in both a non-OSGi environment (say, consumed with Maven) and with those destined to run inside an OSGi container. The convention, in Maven terms, is to work against (a number of)
2.1-SNAPSHOT builds, before finally replacing the version number as
2.1. Often a repository manager (such as Artifactory or Nexus) will rewrite the snapshots to a dated file when published for traceability.
Eclipse PDE build, and thus Maven Tycho, works by explicitly naming each built component, typically with a changing date/timestamp as part of the build. Since each built component gets a new name, the versions may be incrementally installed into an OSGi runtime with the new version overriding another.
Unfortunately, this means that the versions of the 'final' released components also contain a build qualifier, which can in some cases be longer than the name of the artifact itself (e.g.
org.junit_4.8.2.v4_8_2_v20110321-1705). They also aren't consistent in the format of the qualifier (e.g.
Some producers, such as SpringSource, create versions in the form
1.2.3.M1, 1.2.3.M2, 1.2.3.RELEASE which work for both OSGi and Maven consumption.
-SNAPSHOT style versions for OSGi would have solved this problem. It was proposed (and even implemented in Equinox) that the
Bundle-Version syntax could have been upgraded to permit
1.2.3-456 to sort lower than
1.2.3. This could have enabled bundle developers to use the
-SNAPSHOT style variant (with tooling like Tycho and PDE using
-SNAPSHOT as the 'magic replacement value' instead of
.qualifier) for development purposes, and then release
1.2.3 as the only build in that sequence, followed by a bump to
Unfortunately, the concerns raised were speculative rather than empirical:
Furthermore, we also become concerned about the mental complexity of pre-release versions. In numerous discussions within CPEG and with peers, people would get confused over the ordering of versions and whether some version was included in some range. If we, the "experts", couldn't keep it straight in our minds, we might expect others to also have a hard time.
The complication was related to how build ranges are concerned. Existing use cases such as
[1.0,2.0) were considered. In this case, the
1.0 would have permitted snapshot
1.0-* versions, whereas the
2.0 at the other end would not. Ultimately, this rule boils down to If it's an inclusive range, it includes snapshots, and if it's a exclusive range it excludes snapshots which hardly seems difficult to recall.
The risk is that this decision actually dissuades the use of OSGi-generated content. For about a year, there have been discussions on how to represent the Eclipse-built artifacts in a Maven namespace, by mapping the components into an
org.eclipse.* style group and with the full artifact name. However, the proposal has been to just drop all the qualifiers to make it easier for humans to consume, at least from the Maven front end.
This highlights a problem with the use-case of using a qualifier for everything. Developers forget to update the version number and just use the auto-generated number when providing builds, with the result that the Eclipse repository contains multiple artifacts with the same major/minor/patch version number, but different build qualifiers. From a local Eclipse 3.7 instance, upgraded to 3.7.2, the following are just a subset of the plugins with duplicate major/minor/patch versions:
The problem is that these numbers are generally meaningless to anyone who looks at the file system or tries to remember the number. This may not matter if you're using a repository tool such as P2 or OBR to materialise your artefacts, but the majority of the world's build tools are still built upon a
Require-Bundle type of dependency with an explicit version number and name. It also complicates management of many OSGi runtimes where an easy comparison of installed bundles becomes more difficult.
-SNAPSHOT model solves this problem, because at promotion time the version number is explicitly incremented. (This doesn't rule out the possibility of doing a further testing stage after the version number has been finalised; but typically problems found at that stage lead to a bump in the patch level anyway.) This process is used successfully by the Apache Felix project who have a list of releases with short numbers and are easy to re-use in an existing build. Arguably it is easier to build against Apache Felix for headless OSGi builds than Equinox, both because of this and because the artifacts are available in Maven central already.
In InfoQ's opinion this is a missed opportunity. By not following through with the proposed implementation, based on minor concerns, the OSGi core platform expert group have turned a tooling problem into a human problem.
Case point: Scala
Scala has just gone through a long discussion of how to do versioning because of this very problem. The end result is that Scala has now three different versions. For example:
[echo] maven version: 2.10.0-SNAPSHOT
[echo] OSGi version: 2.10.0.v20120403-064802-f2bc58ce1b
[echo] canonical version: 2.10.0-20120403-064802-f2bc58ce1b
Dont understand snapshots
(((develop build test )+ qa )+ production )+
Snapshots forces you to:
(((snapshot build test)+ qa)+ ((release build test)+ qa)+ production )+
Since release requires you to modify the metadata (the versions) you run the chance that there are changes in your code that cause errors. Since any prudent company will require that whatever goes into production is tested, this seems to require an extra test cycle after a release cycle. Since it is unlikely that versions generate errors, this extra test/qa cycle is mostly wasted ... I think.
I personally prefer to have multiple repositories and ALWAYS making the final version in a repository that is only shared with my co-developers. (Package) versions are baselined against the master repository. After QA approves the result, the tested artifacts are moved to the master repository and can then go into production since they are identical (this can be verified with digests/signing).
This means that for any major.minor.micro release there is just ONE instance in the master repository. In bnd(tools) we already ignore the qualifier for resolution reasons since semantically there must not be a difference. The qualifier was intended to describe the build instance, not become everbody's favorite place to let as many angels dance as possible.
In this model, the cycle then becomes.
(((develop build test)+ qa)+ promote production)+
I've no real experience with maven so maybe I am totally wrong ...
Because the multiple repositories sounds so much more attractive I lost the urge to fight for the negative qualifiers. If you really feel strong about them anyway, I think it is fairer to join the alliance and participate in the specification work. It is hard to advocate for something that you do not feel strong about ... These things need to be driven by interested parties.
It is concerning that multiple versions on an artefact only differ in the qualifier.
Forcing a "snapshot" style avoids this pollution of your production namespace as you can only consume released versions.