Deploying OSGi Feature Repositories to a Maven Repository

Once you've started deploying bundles into maven; the next step is to collect your bundles into feature repositories and make them available in your maven repository. (Don't get confused by the terminology - A OSGi feature repository is different than a maven repository)

Turns out it's fairly easy to get setup, since an OSGi feature repository is just an XML file. All you need to do is attach the XML file as an artifact to a maven project and you can deploy it and reference it from ServiceMix (the OSGi container I'm using; it might be possible in others, but I haven't tried).

Here's the process I use to deploy feature repositories:

1. First you need to create the features.xml file you will be deploying. See FuseSource's Documentation for a good overview.

It should look something like:

<?xml version="1.0" encoding="UTF-8" ?>
<features>
<feature name="tool-feature" version="${version}">
<bundle>mvn:us.justjohn.osgi/test-tools/1.1/jar/osgi</bundle>
<bundle>mvn:us.justjohn.osgi/utilities/1.0/jar/osgi</bundle>
</feature>
</features>


Note the ${version}, we'll be using Maven's resource filtering to pull the version number in from the POM file.

2. Create a Maven project and put your features.xml file in src/main/resources. Use the following in your pom.xml file.

<project xmlns="http://maven.apache.org/POM/4.0.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>us.justjohn.osgi</groupId>
<artifactId>test-feature-repo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>Test ServiceMix Feature Collection</name>

<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>target/features.xml</file>
<type>xml</type>
<classifier>features</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>


Let's break this down and see what's going on. First, the maven-resources-plugin is configured to filter all the resources in src/main/resources. This will allow you to put maven properties into your features.xml file. (In the example above I used ${version} to get the version from the POM)

Second, the build-helper-maven-plugin is configured to attach the filtered features.xml file as an artifact with the type xml and a classifier of features ( the classifier is optional, but makes the URL more readable and matches convention.)

This will result in a URL is ServiceMix like:

mvn:us.justjohn.osgi/test-feature-repo/1.0/xml/features


3. Deploy the feature to your maven repository:

$ mvn clean deploy

4. Load the feature repository URL in ServiceMix. (assuming you've already configured ServiceMix with you maven repository)

features:addUrl mvn:us.justjohn.osgi/test-feature-repo/1.0/xml/features

You can verify a successful load with features:listUrl, you should see the new URL listed. Now you're ready to load any features defined in the feature repository, in the example there's only one, "tool-feature". You can check that it's in the list of available features with:

features:list | grep "tool-feature"

You should see something like:

[uninstalled] [1.0 ] tool-feature ...