One of the requirements for the software that we're developing at work is the ability to load components into an OSGi container. This prompted an interesting question from one of the developers I work with about deploying both a regular JAR and an OSGi bundle from his project into our Maven repository. He couldn't access both of the artifacts after deploying them, only the last one deployed, the other returned an error related to "build number not found". After some digging I discovered this was being caused by our use of classifiers.
The way that we'd like to name our artifacts is to append an osgi classifier to the artifact name for the OSGi bundle version. This causes an issue if you try to deploy SNAPSHOT versions of both artifacts to the same maven repository because of a limitation in the Maven 2 format of repository metadata. The metadata only contains one build number and timestamp for the current snapshot of any given version. For reference a Maven 2 artifacts looks like this:
artifactId-version-timestamp-buildnumber-classifier.jar
Because the timestamp and build number are increased every time a new artifact is deployed and Maven 2 only stores one build number / timestamp for snapshots regardless of classifier, you can only ever access the latest deployed artifact. This is a major problem if you want to deploy multiple artifacts with the same snapshot version and different classifiers, such as an osgi bundle and a regular jar artifact. You can only access the most recently deployed artifact, since the build number won't match for any of the other versions with different classifiers.
There are a few different solutions to this:
- Upgrade to Maven 3, the issue is solved in the latest release. (See MNG-4452 for details)
- Disable build numbers by setting uniqueVersion to false in the maven distributionManagement settings
- Use separate Maven repositories for the different build types.
We ended up going with option 3 since we're not at a point where we can upgrade to Maven 3 and we want to have history for the snapshots we deploy.
Here's how we accomplished this:
We already have a profile in our common parent POM to enable OSGi build (change the artifact type to bundle, set the "osgi" classifier, configure the maven-bundle-plugin, etc...) The change I added to the profile was overriding the distributionMangement tag with a different set of repositories for snapshots and releases. While this adds a couple more repositories to maintain, it does have the nice side effect of segmenting all of our OSGi artifacts from the non-OSGi artifacts.
I've also setup a repository group that contains both the snapshot and release repositories in it. This makes the ServiceMix configuration really easy. All we have to do is add the group URL to the list of repositories in the org.ops4j.pax.url.mvn configuration file and we're all set to begin loading bundles into ServiceMix.