HelloWorld example in OSGI

This example describes how to write OSGI code, how to compose manifest file, how to build bundle with Ant and finally how to deploy bundle and start and stop it.

Create new project HelloWorld in Eclipse or any other IDE. Java classes are stored inside src directory. Put framework.jar into lib directory and add it to build path.

HelloThread

First we will create new thread with endless loop that will print 'Hello OSGI' message every 3 seconds.

package si.matjazcerkvenik.helloosgi;

public class HelloThread extends Thread {

private boolean running = true;

public void run() {

while (running) {

System.out.println("Hello OSGI");

try {
sleep(3000);
} catch (InterruptedException e) {
}

}

}

public void stopThread() {
running = false;
}

}

Activator

Activator class is entry point of most bundles and must be declared in manifest file, similarly like class with main method in ordinary Java applications.
Activator class implements BundleActivator interface which requires implementation of two methods: start() and stop(). The OSGI framework loads Activator class at runtime and executes either start or stop method.

Take a look at start() method. The method provides BundleContext object, which is link to the framework itself. In the bundle context you can find information of installed bundle or references to services in other bundles. So in first step we will store reference to bundle context locally in our Activator class. Inside start method we will also start our thread that prints Hello message.

Start method is called when bundle is started by the framework. The same goes for stop method. It is called when the bundle is stopped by the framework. The purpose of stop method is to release all resources and prepare the bundle to shutdown. In our case stop method will stop the Hello thread.

package si.matjazcerkvenik.helloosgi;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;

public class Activator implements BundleActivator {

private BundleContext bc = null;
private HelloThread t = null;

public void start(BundleContext ctx) throws Exception {

bc = ctx;
System.out.println("Starting "
+ bc.getBundle().getHeaders().get(Constants.BUNDLE_NAME)
+ "...");

t = new HelloThread();
t.start();

}

public void stop(BundleContext ctx) throws Exception {

t.stopThread();

System.out.println("Stopping "
+ bc.getBundle().getHeaders().get(Constants.BUNDLE_NAME)
+ "...");
bc = null;

}

}

Manifest file

Manifest serves to define relationship with the framework. Manifest file tells the framework which class implements start() and stop() methods, defines dependencies of other packages (such as framework itself) and other metadata like name of the bundle, version, etc... Manifest also declares which services the bundle has to offer to other bundles (not in this example but in next example).

Usually I put manifest.mf file in META-INF directory inside project.

Manifest-Version: 2.0
Bundle-Name: helloosgi
Bundle-SymbolicName: helloosgi
Bundle-Version: 1.0.0
Bundle-Description: HelloOsgi Bundle
Bundle-Vendor: Knopflerfish
Bundle-Activator: si.matjazcerkvenik.helloosgi.Activator
Bundle-Category: example
Import-Package: org.osgi.framework

Building a bundle

Bundle is compiled and built with Ant just like any other jar file. This Ant build file uses lib/framework.jar to compile the bundle. Compiled classes are stored in build/classes directory and final bundle jar file is stored inside dist directory. Notice that manifest file is also included in the jar file.

<?xml version="1.0" encoding="UTF-8" ?>
<project name="helloosgi" default="all" >

<property name="lib.dir" location="lib" />

<target name="all" depends="clean,init,compile,jar" />

<target name="init" >
<mkdir dir="build/classes" />
</target>

<target name="compile" >
<javac destdir="build/classes" debug="on" srcdir="src" >
<classpath>
<fileset dir="${lib.dir}" includes="**/*.jar" />
</classpath>
</javac>
</target>

<target name="jar" >
<jar basedir="build/classes" jarfile="dist/${ant.project.name}.jar"
compress="true" includes="**/*" manifest="META-INF/manifest.mf" />
</target>

<target name="clean" >
<delete dir="build" />
</target>
</project>

Deploying and starting bundle

In Knopflerfish OSGI bundles can be installed via GUI. Select File -> Open Bundle File and select helloosgi.jar we just built. New icon appears in Knopflerfish Desktop. Bundle can also be installed by dragging and droping the jar file onto the Knopflerfish Desktop.
Bundle is started by clicking the Start button. Once bundle is started, you should see 'Hello OSGI' messages in Knopflerfish Console.
Bundle is stopped by clicking on the Stop button and uninstalled by clicking on Uninstall button.

Deployment of bundle can also be achieved via console.

$ java -jar framework.jar
> install file:jars/hello/helloosgi.jar
> start helloosgi.jar

Base directory to install bundles is where framework.jar was started.