Sunday, November 04, 2012

Overview of OSGi

What is OSGi?

OSGi is a module system and service platform for the Java platform.

For the module system, it extends the code level visibility controls that Java provides via the private, protected, public and package-private access. An application is usually packaged as multiple jars in java. Some of these are external libraries. With OSGi it is possible to specify version for a jar and dependency information between jars.

OSGi enables Service Oriented Architecture in a Virtual Machine. It provides APIs for providing a way to register services, discover and bind to them.


Specifications


The OSGi Alliance is an industry backed non-profit organization that manages the OSGi specifications. There are a many implementations like Apache Felix, Eclipse Equinox and Knopflerfish. Building on top of the core OSGi framework are runtimes that provide additional services like Apache Karaf.

Architecture


OSGi Platform

The OSGi platform is composed of the Framework and Standard services. The framework is the runtime that implements and provides OSGi functionality. The standard services define reusable APIs for common tasks.

Core framework

The core framework itself can be broken down into 3 layers - Module, Lifecycle and Service. Each layer is dependent on the layer below. The Module layer has to be used by an application but the Lifecycle and Service layers are optional.

1. Module Layer
In OSGi the unit of modularity is called a Bundle. A Bundle is basically a jar file containing additional metadata in headers with an additional file - META-INF/MANIFEST.MF.

Headers Bundle-SymbolicName and Bundle-Version are used to uniquely identify a Bundle and its version. Using the header Export-Package the Bundle can specify the packages that are visible to other packages. Import-Package and Require-Bundle are used to specify the dependencies of a Bundle.

2. Lifecycle Layer

There are 4 phases of a Bundle lifecycle
  1. Installation - The bundle jar has to be installed first from a URL. The framework automatically resolves its dependencies based on the Import-Package and Require-Bundle headers. Resolution happens transitively for all the dependent bundle as well.
  2. Execution - When the Bundles classes are first accessed or the bundle is explicitly started, it moves to a starting state
  3. Update - Bundles may be updated to a different version using the API
  4. Removal - Finally bundles may be uninstalled.
Some of the important APIs that allow this functionality are-
org.osgi.framework.BundleActivator
org.osgi.framework.BundleContext
org.osgi.frameword.Bundle

3. Service Layer

The OSGi framework allows registration of services, discovery and binding to them. Bundles may be installed and uninstalled allowing for dynamic services and possibly multiple implementations.

The org.osgi.framework.BundleContext class provides APIs for this service layer.

Services

An OSGi platform provides core services some of which are-
  • Package Admin (org.osgi.service.packageadmin) provides the ability to control and reflect over bundle and package level resolution
  • Start Level (org.osgi.service.startlevel) controls the relative order of bundle startup by assigning start levels to bundles
  • Service Hooks (org.osgi.framework.hooks.service) allows bundles to monitor and limit service registry events and access
Some of the optional services are-
  • Log (org.osgi.service.log) for logging by bundles
  • HTTP (org.osgi.service.http) for a HTTP server with Servlet support
  • Configuration Admin (org.osgi.service.cm) Manages bundle configuration data storage and injection
  • Preferences (org.osgi.service.prefs) for management of Preferences
  • Event Admin (org.osgi.service.event) for publish-and-subscribe and topic-based event notification

Summary

OSGi does provides some valuable extensions to the core java language. Just being able to specify packages to external clients allows to design APIs without leaking unnecessary information. Classpath resolution is also well managed.
The service layer further adds to the idea of well defined APIs.

Being based on plain java classes the framework does not feel heavy like EJBs. However figuring out how to use a particular runtime is not an easy task.

Integrating with existing code and converting them to bundles is also non-trivial. If jars are not well designed APIs then there is always a problem that there are some references that will never be cleaned causing a leak. Existing code also needs to be refractored to use the OSGi services of logging and configuration.

In all OSGi has value but there is also a cost to using the framework.