Creating OSGi bundles of your Maven dependencies

Working with Maven and OSGi is very straightforward. You add your dependencies in the pom.xml and then the maven-bundle-plugin does the dirty work, creating the correct headers for the OSGi descriptor and of course adding them to your compile classpath for your developing phase.

But then you add your fantastic new OSGi bundle to the container and it doesn't work........ops, what went wrong ???

The problem is in the dependencies into the OSGi container, here the Maven dependencies can be unavailable and therefore our Bundle is unable to start. 

The answer to this problem is easy: "Add those missing bundles !!!!". Yes, easy to say, long and boring to do. Most libraries are not OSGi bundles and we should repackage all them with OGSi headers to be loaded into the container. 

maven-bundle-plugin to the rescue !!!

But there is a smarter way to do things: looking at maven-bundle-plugin documentation there are goals that repackage our Maven dependencies as OSGi Bundles, with very few configurations. 

The best thing to do is to create a profile inside our bundle pom with the bundle plugin configured with the goal options and lifecycle configuration:

            <profile>

                  <id>create-osgi-bundles-from-dependencies</id>      

                  <build>

                        <plugins>

                             <plugin>

                                   <groupId>org.apache.felix</groupId>

                                   <artifactId>maven-bundle-plugin</artifactId>

                                   <version>2.0.1</version>

                                   <extensions>true</extensions>

                                   <executions>

                                         <execution>

                                               <id>wrap-my-dependency</id>

                                               <goals>

                                                     <goal>wrap</goal>

                                               </goals>

                                               <configuration>

                                                     <wrapImportPackage>;</wrapImportPackage>

                                               </configuration>

                                         </execution>

                                   </executions>

                             </plugin>

                        </plugins>

                  </build>   

            </profile>

 

Here we can notice some things about configuration:

Now we can launch Maven to let the plugin do the dirty work:

mvn -Pcreate-osgi-bundles-from-dependencies bundle:wrap

Once finished you can find your bundles inside the target/classes folder, but this can be personalized changing the outputDirectory of the Maven build:

    <build>

        <directory>${basedir}/bundles</directory>

        …

        …

This can be done easily and with no negative implications thank to the custom profile for this build.

Maven scope to the rescue

Now that we know how to create those bundles, the next question is "how can I choose which bundles ???"

Let's make an example, suppose I have three dependencies:

In this caso I could declare those dependencies this way (pseudo-pom):

            <dependency>

                  <artifactId>libraryA</artifactId>

                  <scope>provided</scope>

            </dependency>

            <dependency>

                  <artifactId>libraryB</artifactId>

            </dependency>

            <dependency>

                  <artifactId>libraryC</artifactId>

                  <scope>runtime</scope>

            </dependency>

 The bundleall/wrap Mojo uses only dependencies at compile/runtime scope, this way we can be sure that only needed dependencies will be OSGified.