A New Approach to Software Development
A Gentle Introduction to OSGi
This is an attempt to give readers the necessary clues to start developing on the OSGi platform. This article will offer reasons to use such technology, and introduce philosophy and key tools.
For over a decade a group of companies interested in providing software for embedded devices, then for more usual platforms (desktop or server side ones,) started to work on writing specifications for a logical platform aimed at hosting applications while placing emphasis on different criteria:
• small footprint
• dynamic aspect
Among them we can find:
• BMW Automotive
• Siemens, etc...
OSGi specifications are divided into two major books:
• OSGi Core, contains the base API for working with OSGi, especially the stuff related to bundles.
• OSGi compendium, offering specifications for the whole set of standard services, services available to any compliant OSGi container.
This tale, which started with a focus on embedded devices, turned out to embrace the whole spectrum of software. Success stories, products based on OSGi, are the best way to show what you can do with OSGi: Eclipse (based on an OSGi implementation called Equinox since 3.1 release), Glassfish 3 or Jonas 5 (JEE application servers).
For extended features, we may look to extended specifications with:
• Enterprise OSGi, offering an enhanced set of APIs aimed at easing enterprise centric development (JPA integration.)
• Distributed OSGi, offering mechanisms to distribute applications running on top of a collection of Java Virtual machines.
OSGi specifications use Java as a base while avoiding classic Java headaches with a special classloading policy. The OSGi classloader deviates from the standard Java classloading policy while offering a way to support these impossible features:
• running several versions of the same component inside the same JVM
• true class reloading
With such power, efficient application reloading becomes possible. So OSGi needs to extend standard Java to deliver components, that's why it just wraps the standard Java deployment format (.jar) while adding metadata into the misunderstood META-INF/MANIFEST.MF file.
The OSGi platform hosts components offering services to other components (called bundles in OSGi jargon) and may depend on services offered by other bundles. It’s a real microcosm but with a dynamic facet, where services can appear or disappear at any time. Figure 1 models such relationships between bundles.
MANIFEST.MF file will contain all meta information required to express such relationships for each bundle. The following listing shows contents from one bundle requiring at runtime one service for logging purpose (it’s the standard OSGi logging service), this service may have different implementations but that’s not the problem for our code. Please refer to the sample code provided in this article.
In such a dynamic environment, components (packaged as jar files called bundles) may be installed, deployed, stopped or removed. Figure 2 from the OSGi Alliance website shows transitions into the different states possible for a bundle. The next section introduces OSGi shells, offering commands to control bundles states.
OSGi defines containers made to host applications delivered as bundles (the unit of deployment). The runtime controlling your applications is called a shell like Unix shells manage programs. Working with OSGi means delivering (provisioning) your application as bundles and deploying them into a shell. You may choose between different equivalent OSGi implementations:
• Knopflerfish from Makewave
You may use extensions from the OSGi specifications and use:
• Paremus shell (for Distributed OSGi)
• Apache CXF
• Eclipse ECF
or for Enterprise OSGi products like:
• Apache Karaf is a useful shell too
What can a shell do for you? Just getting full access to the bundles lifecycle while also providing an elegant way to integrate your own commands. If the commands list may change from one product to another, every shell will give you at least access to the bundles lifecycle, so you will be able to :
• install/uninstall a bundle
• start/stop a bundle
• get the list of installed bundles with their current state.
Choosing a Shell …
It’s a matter of choice but the writer uses felix for its very low footprint and tests its plugins with knopflerfish for convenience (graphic shell is very close to the specifications).
Services & Tracking
From the OSGi point of view, a service is just a plain Java interface, this interface may be implemented in different manners. In such a dynamic environment, getting references to one of the compatible implementations is an absolute requirement. You may use one of the following ways to achieve this goal:
• use standard OSGi API.
• use the ServiceTracker to get a more convenient result.
• use the SCR or Declarative Services, to have an easy and powerful way to inject dependencies at runtime, like Spring Core does (Spring simply does dependency injection)
OSGi Standard Services List
OSGi defines the following list of services:
• http service, to expose with a Web interface resources contained in one bundle.
• logging service, to trace events encountered during runtime.
• event services, is a mono JVM (OSGi container related only) messages broker.
• configadmin, offers a complete API dedicated to storing configuration data for your bundles.
• preferences, describes how to store user preferences.
• metatype, enables modelling of meta data related to your structures and to handle them gently into GUIs.
• SCR or Declarative Services, is the way to inject dependencies into any service at runtime.