The OSGi Alliance Service Platform enables new & exciting services and applications for networked devices.OSGi technology improves time-to-market and reduces costs of manufacturing and development with unique new after-market sales opportunities for device manufacturers and service providers
THere are a number of implementations of the OSGi framework avaiable:
THis article is intended to be a view of OSGi from 10,000 ft. For a much more thorough introduction to OSGi work through this oscar tutorial.
With OSGi, plugins are referred to as Bundles. A bundle is essentially just a jar file which contains OSGi specific meta-data in in its manifest. This meta-data includes:
- the id and version of the bundle
- dependencies on other bundles
- which packages are available to other bundles
Lets jump into our example. We will create 3 bundles:
- One containing the service interface called example.service.
- One containing the implementation for WMS called example.service.wms.
- One containing the implementatino for WFS called example.service.wfs.
As of Eclipse 3.2M1, Eclipse can create OSGi manifests for other OSGi frameworks.
Creating the three projects we get:
In each project we see the MANIFEST.MF file mentioned above. Also notice the Activator class in each bundle. A bundle must have an activator class and it must be listed in the manifest. An activator is an implementation of the org.osgi.framework.BundleActivator interace.
The activator serves a number of purposes.
1. Provides lifecycle events to the bundle.
2. Provides the bundle with a context, which gives the bundle access to other types of functionality such as the ServiceRegistry (explained in more detail below).
As stated above each bundle requires a manifest.
Important things to note:
- The activator class example.service.Activator is specified as the bundle activator.
- The example.service package is exported since our other bundles depend on the Service interface.
Important things to note:
- The activator class example.service.wms.Activator is specified as the bundle activator.
- The Require-Bundle attribute specifies that this bundle imports the example.service package. This is due to the fact that the WMS class implements the Service interface.
- No packages from this bundle are exported.
The wfs bundle manifest is similar to the wms bundle manifest.
As stated above each bundle requires an activator.
Nothing special in the activator for the example.service bundle. It does nothing.
In the wms activator, we see that a new WMS service is created and registered with the context. The service is registered under the name of a class, usually an interface that the class implements. As we will see later, this now allows our WMS service to be accessible to other bundles.
And similar to wms, the wfs service is registered as well.
So we have a few bundles, how do we run them. Well first we need an osgi runtime. We will use Oscar.
- Download oscar-1.0.5.jar
- Install oscar with the command
- Download example.service.jar
- Download example.service.wfs.jar
- Download example.service.wms.jar
To start up osgi navigate to the directory to where you installed Oscar, and execute oscar.bat (or oscar.sh). When prompted for a profile, just enter 'example'. This starts up a console which we can use to control Oscar. The first thing we will do is install our bundles. This can be done by executing the following commands at the osgi console. The final command ps lists all bundles.
|replace /home/jdeolive with a valid path.|
So this is nice but it doesn't do anything. WE have installed our services but noone is around to consume them. What we need is a client. Our client will be a simple servlet that performs the following task:
When a http request comes in, the url of the request is used to locate a particular service. If a service is located then the service outputs its capabilities document, otherwise an error is output.
Similar to our services, our client will also be a bundle. Lets call it example.service.client. The following is its manifest:
Note the imports: javax.servlet,javax.servlet.http,and org.osgi.service.http. The first two are simply the java servlet api. The thrid is an http osgi bundle whose purpose is to provide a mechanism to publish our servlet. The last is the Service API provided by the example.service bundle.
The activator for our client looks up the http service and uses it to install the servlet under the context: /example.
The servlet uses the BundleContext to obtain references to the various services that have been installed.
First download example.service.client.jar. Then execute the following commands at the oscar command line:
|You need administrative priveleges on the machine in order to run the Http Service over port 80.|
The first two commands install the OSGi Http Service from the Oscar Bundle Repository. The last commands installes our client bundle. Once the commands have completed successfully try the following:
So you might be saying "So what, what is this going to buy me when I am developing applications?". And the answer is "Well not much by itself." The power of OSGi is what is built on top of the core. Much work has gone on to develop bundles that provide services that the application programmer wishes to use. For instance, the following is a repository of bundles which provide services such as HTTP,Logging,JMX, and many more.
I would like to mention Equinox, which is an implementation of OSGi that is used with Eclipse. While still in the early stages of development, it shows much promise. As a background, part of Eclipse 3.0 inolved a transition from there custom plugin model to OSGi. Go here for a full brackground.
The point I would like make is that much of the Eclipse internals are being factored out into Equinox. Anyone who has developed with Eclipse can tell you that it has a pretty sweet plugin model. The idea of extensions and extension points are a very powerful construct.
Enough about the technology, lets apply our criteria.
Not much has to be said here, OSGi has a top knotch plug-in architecture. It was so good that IBM decided to build the Eclipse plug-in architecture around it. Lets discuss some of the high points.
Explicit declaration of imports and exports. This has a couple of benefits. The first is that it provides the framework enough information to tie bundles together, while at the same keeping the individual bundles isolated from each other. All dependency complexities are handled by the framework. However most programmers are not used to doing this and forgetting to do can lead to the dreaded "ClassNotFoundException". It also makes describing bundle dependencies pretty verbose.
One think I like is that it allows programmers to clearly define what is api and what is not. We have all run into the problem of client code becoming dependent on framework code that isn't part of the API. With this type of explicit import/export system interface is clearly seperated from implementation.
The OSGi API is well documented and they have published a set of Java interfaces which have been very well javadoc'd.
Tooling support comes from Eclipse. The tools however are still geared to the specific Eclipse OSGi implemetnation, however the 3.2 series has introduced some support for generating OSGi manifests for other OSGi frameworks.
The strong programming model is also there. Component interaction is well defined via bundle context and service registry.
This is where we start to see OSGi fall a bit short. I ran an experiment where I tried to fire up Equinox from a servlet in a J2EE app and the two were in conflict. So for now it seems that OSGi is its own beast. That being said there is work going on to remedy this situation. If you are interested in the specifics see the following bug report.
It appears that OSGi is here to stay. IBM has put a fairly large steak in it. There is also some cool stuff going on with other standards such as JSR-277 (Java Module System).