I warmed up to the idea of OSGi after reading an introduction like : “Use OSGi to service enable your JVM”. For background, we at MindTree have created a SOA based J2EE delivery platform built on open source technologies – primarily Spring. In this framework, we expose POJOs as services using Spring remoting and access them via the Mule ESB. The idea of being able to expose POJOs as services without having to remote enable them made OSGi an interesting proposition.

I chose Spring Dynamic Modules(Spring DM) for three reasons:

  • I hoped to leverage all of Spring’s capabilities while writing my service
  • Ability to manage my service POJOs as Spring beans
  • Easy migration path for our framework

My test was to write a POJO, declare it as a Spring bean and an OSGi service (using Spring DM) and eventually access the service from a standalone application. This completes a typical usage scenario. I used the “simple-service” sample code that comes with the Spring DM distribution (version 1.1.0).

I faced issues either because I was not able to find the right documentation or because it was simply not there. I encountered and eventually overcame the following issues:

  • Ability to launch an OSGi container in standalone mode and without the prompts – most samples on the internet showed me how to bring up Equinox with the “osgi>” prompt. This was easily solved though.
  • Ability to load all the required OSGi bundles *before* I could load my bundle
  • Look up a published service from the bundle I deployed and invoke it from my standalone code

A few lessons learned from this exercise are:

  • OSGi is very strict when it comes to class visibility and loading. Parent class loader delegation does not apply – something we are very used to in J2SE and J2EE applications
  • It is easy to share services and packages between bundles. Not all that easy if you want to share between a bundle and a non-OSGi client application. For e.g, you cannot simply type-cast a service you have looked up to an interface that is packaged in the bundle and available on your local classpath.
  • Boot path delegation (creating fragment bundles i.e extensions to the system bundle) can help address the above need but must be used selectively and carefully in order to preserve the benefits of OSGi.
  • All bundles are loaded asynchronously. You need to account for this before you look up any service.

I have replicated below the manifest contents from my fragment bundle (one that exports the common interfaces & classes) and the service bundle (one that imports the common interfaces and implements the service):

Fragment manifest:

——————————————————–

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: m1000350
Build-Jdk: 1.5.0
Bundle-Version: 1.0
Bundle-SymbolicName: org.springframework.osgi.samples.simpleservice.boot
Bundle-Name: Simple-Service-Sample-boot
Bundle-Vendor: Spring Framework
Fragment-Host: system.bundle <— note this extension
Export-Package: org.springframework.osgi.samples.simpleservice <— note this export
Bundle-ManifestVersion: 2

———————————————————

The manifest for my service bundle looks like:

——————————————————–

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: m1000350
Build-Jdk: 1.5.0
Bundle-Version: 1.0
Spring-Context: *;create-asynchronously=false <— Spring DM integration
Bundle-SymbolicName: org.springframework.osgi.samples.simpleservice
Bundle-Name: Simple-Service-Sample
Bundle-Vendor: Spring Framework
Bundle-ManifestVersion: 2
Import-Package: org.springframework.osgi.samples.simpleservice <— note this import

——————————————————–

I have attached the code for my sample application. Unfortunately, the complete Spring DM integration (the use of OsgiBundleXmlApplicationContext) does not work and I have posted a question on the Spring support forum :Spring DM issue.

I was however able to invoke the OSGi service from my non-OSGi client.

Disclaimer: The code is just a sample and is not validated in its approach or manner of using the OSGi platform.

OSGiTest – Rename to .java and open in your favorite editor

Advertisements