Wednesday, June 24, 2009

OSGi Quick Start

Again, ANT is the tool of choice for managing a simple project that utilizes open source components. I am reading Craig Walls' excellent book "Modular Java", published by the Pragmatic Programmers. The book has some excellent examples and incorporates additional tools in the projects, integration being the raison d'ĂȘtre of OSGi. This example is the basic 'hello world' program and is similar to the example published in the OSGi wikipedia article.

This is the first time I've used ANT's manifest task. OSGi requires a manifest of a particular format be added to the jar file. Using the manifest task eliminated the need to create and manage a separate manifest file.
<project name="hello-activator" default="jar" basedir=".">
 
 <property name="version" value="1.0.0"/>
 <property name="buildfile" value="${ant.project.name}-${version}.jar"/>

 <property name="src"      location="src/main/java"/>
 <property name="build"    location="build"/>
 <property name="dist"     location="dist"/>
 <property name="manifest" location="build/META-INF/MANIFEST.MF"/>
 <property name="lib.dir"  location="../../../lib/spring-osgi-1.1.2/lib"/>
 <path id="classpath">
   <fileset dir="${lib.dir}" includes="**/*.jar"/>
 </path>
 
 <target name="clean">
   <delete dir="${build}"/>
   <delete dir="${dist}"/>
 </target>
 
 <target name="init" depends="clean">
  <mkdir dir="${build}"/>
  <mkdir dir="${build}/META-INF"/>
  <mkdir dir="${dist}"/>
 </target>
 
 <target name="compile" depends="init">
  <javac srcdir="${src}"
      destdir="${build}"
      classpathref="classpath"/>
 </target>
 
 <target name="jar" depends="compile">
   <manifest file="${manifest}" mode="update">
    <attribute name="Bundle-ManifestVersion" value="2"/>
    <attribute name="Bundle-SymbolicName"    value="com.pragprog.HelloWorld"/>
    <attribute name="Bundle-Name"            value="HelloWorld"/>
    <attribute name="Bundle-Version"         value="1.0.0"/>
    <attribute name="Bundle-Activator"       value="com.pragprog.hello.HelloWorld"/>
    <attribute name="Import-Package"         value="org.osgi.framework"/>
   </manifest> 
   <jar jarfile="${dist}/${buildfile}" basedir="${build}" manifest="${manifest}"/>
 </target>
 
</project>
package com.pragprog.hello; 

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

public class HelloWorld implements BundleActivator { 
 public void start(BundleContext ctx) throws Exception { 
  System.out.println("Hello World!"); 
 } 
 public void stop(BundleContext ctx) throws Exception { 
  System.out.println("Goodbye World!"); 
 } 
} 
After creating the Java and build.xml files as shown above, execute ant. Still at the command line, run equinox by executing java -jar ~/dev/lib/spring-osgi-1.1.2/lib/org.eclipse.osgi-3.2.2.jar -console

Equinox presents the osgi> prompt. From this prompt, load the jar file and execute the service.
osgi> install file:dist/hello-activator-1.0.0.jar                             
Bundle id is 1

osgi> ss

Framework is launched.

id State       Bundle
0 ACTIVE      system.bundle_3.2.2.R32x_v20070118
1 INSTALLED   com.pragprog.HelloWorld_1.0.0

osgi> start 1
Hello World!

osgi> stop 1
Goodbye World!

osgi>