OSGi Development with Knopflerfish – Part 2: The Code

Now that we have Eclipse and Knopflerfish installed let's get into some code. This OSGi bundle will roll a random six-sided die every second and print the result to the Knopflerfish Desktop console.

Creating the RandomRoll Project

Click File -> New Project and select OSGi Bundle

Fill in the project information, I am going to call this project RandomRoll.

This is the OSGi specific information, make sure you check the "Create Activator" class box (More on this later.)

bundle.manifest

The manifest file contains all of the OSGi required information for your bundle. The Eclipse OSGi plugin has a built-in editor for the bundle.manifest file to make editing it a little easier on you.

Your default bundle.manifest file should look like this.

Manifest-Version: 1.0
Bundle-Name: RandomRoll
Bundle-Description: Roll a die every second
Bundle-Activator: RandomRoll.Activator
Import-Package: org.osgi.framework
Bundle-Vendor: Tutorial
Bundle-ManifestVersion: 2
Bundle-SymbolicName: RandomRoll
Bundle-Version: 1.0.0

RandomRoll.java

This is where the logic of our OSGi application lies. We'll treat the RandomRoll class just like any other class. The only OSGi requirement is that RandomRoll must extend java.lang.Thread.

package RandomRoll;

import java.util.Random;

public class RandomRoll extends Thread {

	private boolean running = true;

	public RandomRoll() {
		super("RandomRoll thread");
	}

	public void run() {
		while (running) {

			System.out.println("Roll: " + rollDie());

			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				System.out.println("Sleep ERROR: " + e);
			}
		}
		System.out.println("RandomRoll Thread Stopped");
	}

	public void stopThread() {
		System.out.println("Stopping RandomRoll Thread");
		this.running = false;
	}

	private final int rollDie() {
		Random random = new Random();
		return random.nextInt(6) + 1; //1-6
	}
}

Activator.java

Activator.start() will run when the bundle is executed by Knopflerfish. And -as I'm sure you can guess- Activator.stop() will get executed when the bundle is finished executing (when you click the stop button.)

package RandomRoll;

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

public class Activator implements BundleActivator {

	public static BundleContext bundleContext = null;
	private static RandomRoll randomRoll = null;
	
	public void start(BundleContext context) throws Exception {
		System.out.println("Rolling the dice...");
		Activator.bundleContext = context;
		randomRoll = new RandomRoll();
		randomRoll.start();
	}

	public void stop(BundleContext context) throws Exception {
		System.out.println("No longer rolling dice...");
		randomRoll.stopThread();
		randomRoll.join();
	}
}

Building the RandomRoll.jar Bundle

This is my least favorite part of Java programming, I think the deployment of .jar files is tedious at best and it's really annoying to have.... wait... what's that... the .jar bundle for RandomRoll is already built for me? Nice! Simply look in the /out folder in RandomRoll to find a nice .jar file just waiting to be installed and run.

Speaking of... now it's time to move on to the final stage of this tutorial and run our new OSGi bundle.

This is Part 2 of a 3 part introduction to OSGi and Knopflerfish.
SOA OSGi Development with Knopflerfish – Part 1: The Setup
SOA OSGi Development with Knopflerfish – Part 2: The Code
SOA OSGi Development with Knopflerfish – Part 3: The Execution

Creative Commons License

What do you think?