Sunday, 20 October 2013

converting an ordinary jar into an OSGi bundle (with maven and bnd)

Sooner or later, when dealing with OSGi, you'll find the need to utilize a third-party library which - unfortunately - was not written with OSGi in mind.

Depending on what exactly this library does, it might not be easy to convert it into an OSGi bundle. For example, if it depends a lot on Class.forName(...) constructs, it might be better to look for an alternative implementation, if that exists. Or, if that library depends heavily on further libraries and jars, you might have to convert all of those into OSGi bundles themselves, transitively... which is no fun, especially as you will not know if it will work at all until the end.

Having said that, sometimes it can be easy. A well-written library with low dependency profile, not relying on some fancy class-finding tricks can be converted into an OSGi bundle very easily.

For the following to work, I assume you are using maven.

For our example, I will pick a library I am using myself, which is not OSGi-compatible by default, stringtemplate. You can download the stringtemplate jar, and a quick look at its MANIFEST.MF files content will show you that it is not an OSGi bundle. In fact, with a manifest file not bigger that 122 bytes, you don't even need to open that file to know that you are not dealing with an OSGi bundle.

A simple pom.xml, like the one below, together with a minimal instruction file, will convert the referenced library into an OSGi bundle.

Please note, that the second file, osgi.bnd is referenced in the first one with a leading minus "-" sign.

Update: It seems like the pom setup does not work with the newest version of maven-bundle-plugin (2.4.0), you have to use 2.3.7 to make it work. I was not able yet to figure out why this happens. Thanks to Thomas Newman for the feedback!

Running "mvn clean install" now will create an OSGi bundle that you can deploy to a repository and use in your OSGi framework. Depending on how you use the library, you might have to tweak the contents of the osgi.bnd file to adjust the bundles requirements and capabilities to your context. After all, the original jar version of the library never dealt with OSGi-related concepts, so there might be some work left for you.

From my personal experience I have to add that I was using this approach quite often when starting using OSGi - I was tempted to use a lot of code which was not OSGi-aware. Over the years, for some reason, this need to utilize something from outside the OSGi world became less and less. I guess that, by now, many libraries became OSGi-aware (which is great), and, that - if you look for it - you will find OSGi-compatibly alternatives to many of your needs.

References:

  1. bnd - the tool behind the magic
  2. maven-bundle-plugin - the tool making bnd work inside maven
  3. example project on github - check out the code yourself and try it.