Monday, February 4, 2008

Open Your Eyes to OSGi

Summary This post covers setting up a an OSGi development environment with Eclipse Equinox. It demonstrates running OSGi from a command prompt and from the Eclipse Equinox framework. The next post will cover how to run the Equinox JSP, JSTL, and Struts OSGi example projects on an embedded Jetty server.

Open Your Eyes to OSGi

OSGi was not on my radar for 2008. I just happened to start a project this month for a new client that required OSGi. The project involves writing Servlets to run on an Arcom Zeus XScale PSA270 Single Board Computer.



It was only after I started learning about OSGi that I discovered just how popular it has become. Peter Kriens attested to the growing prominence of OSGi in his presentation, OSGi, The Future of Java? , at JavaPolis '07. Here are some other signs that OSGi is on the rise:


Although my immediate need is to develop a CDC-1.0/Foundation-1.0 compliant OSGi package to deploy on an embedded Linux device, my eye is on the longer term goal of building hot-deployable Web applications using Struts 2.0 and Spring-OSGi.

For today's post I am setting up Eclipse 3.3.1 for OSGi on my family's Vista machine. My previous set-up was done with Eclipse 3.2.2 (per client's request) on my Ubuntu workstation--my primary development platform for Byteworks. If you use Eclipse 3.2.2 you will need to install the Service Activator Toolkit (SAT) separately. It magically appeared on Eclipse Europa after installing the Equinox SDK (below).

Get your First Taste of OSGi

Prerequisites: Java must be installed and in your System path.

You have already had a taste of OSGi... every time you install an Eclipse plug-in. This is a taste of running OSGi outside of Eclipse.

  1. Download org.eclipse.osgi_3.3.1.R33x_v20070828.jar from the Eclipse Equinox site.
  2. Place the JAR in a temporary folder.
  3. Open a command window and "cd" to the folder where you placed the JAR file.
  4. Type: java -jar org.eclipse.osgi_3.3.1.R33x_v20070828.jar -console
  5. The OSGi command prompt should appear ("osgi>").
  6. To see a short status type "ss" and press ENTER.
 C:downloads>java -jar org.eclipse.osgi_3.3.1.R33x_v20070828.jar -console
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.1.R33x_v20070828

The status output shows that your OSGi environment is empty except for the OSGi bundle itself, which is ACTIVE.

Lets' deploy something else to make this example more interesting. We'll use the install command to download and install the Oscar Bundle Repository plug-in.

  1. At the osgi> prompt enter this command: install http://oscar-osgi.sf.net/repo/log/log.jar
  2. Type "ss" to see its status and bundle number.
  3. Type "start n" where "n" is the bundle number.
  4. Type "ss" again to see the new status.

    Installing and Starting a Bundle osgi> install http://oscar-osgi.sf.net/repo/log/log.jar
    Bundle id is 1

    osgi> ss

    id State Bundle
    0 ACTIVE org.eclipse.osgi_3.3.1.R33x_v20070828
    1 INSTALLED http://oscar-osgi.sf.net/repo/log/log.jar [1]

    osgi> start 1

    osgi> ss

    id State Bundle
    0 ACTIVE org.eclipse.osgi_3.3.1.R33x_v20070828
    1
    ACTIVE http://oscar-osgi.sf.net/repo/log/log.jar [1]

Lastly, type "help" to get a list of OSGi commands. We will use "close" to close and exit.

Setting up Eclipse for OSGi Development

Prerequisites - To start this set-up you need Eclipse Europa installed and to be familiar with its use. You should also have a good working knowledge of Java. The desired Java SDK environments also need to be installed. For my CDC-1.0/Foundation-1.0 project I must be able to run on Java1.3.1, so have it installed along with Java 1.4.2, and Java 1.5.

Install the Eclipse Equinox SDK Plug-in (optional)

If you are using Eclipse Europa you already have the OSGi tools necessary to complete this example and can skip to OSGi Housekeeping.

  1. Download the latest Eclipse Equinox release. I chose eclipse-equinox-SDK-3.3.1.1.zip.
  2. Unzip the file and copy the contents of the plugin and features folders to the corresponding folders of your Eclipse installation folder.

OSGi Housekeeping

Make sure that you have installed the JVMs you wish to use and that you have mapped each OSGi Execution Environment to one of the JVMs. Go to Window --> Preferences --> Installed JREs --> Execution Environments. Take a moment to map all the environments listed. You shouldn't have to use Java 1.3 and 1.4. I was just trying to get is close as possible to the target execution environment for my target embedded Linux device.


Creating an OSGi Project

  1. Choose File --> New --> Project... --> Plug-in Development --> Plug-in Project.
  2. Give your project a name and choose standard OSGi framework at the bottom of the Project Wizard and click Next.

  1. Deselect Generate an Activator on the next page. We will do ours by hand later.

  1. Accept the prompt to switch to the plug-in development perspective.
  2. Right click on the project and choose Preferences --> Java Build Path --> Libraries.
  3. Select JRE System Library and click the Edit button.
  4. Change the JRE System Library to be CDC-1.0/Foundation-1.0.

  1. Click Java Compiler in the list on the left.
  2. Change the Compiler Compliance level as needed. In my case, I chose 1.3.
  3. Click OK to close the Properties dialog.
  4. When the project opened the Manifests Wizard automatically appeared.
  5. Open the Dependencies tab and expand the Automated Management of Dependencies section.
  6. Click the Add button in that section.
  7. Select the org.eclipse.osgi bundle from the list.
  8. Click the Add button on the top, right of the screen to import a JAR file from the org.eclipse.osgi bundle.
  9. Locate org.osgi.framework from the list and select it. The org.osgi.framework JAR contains the Bundle Activator class needed for the next step.
  1. Select the src folder and create a new package named com.myfirst.osgi.
  2. Select the com.myfirst.osgi package and create a new class named MyFirstActivator that implements the org.osgi.framework.BundleActivator interface. Check the option to Implement Abstract Methods. The class should look something like this:

    Initial Activator Code package com.myfirst.osgi;

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

    public class MyFirstActivator implements BundleActivator {

    public void start(BundleContext context) throws Exception {
    // TODO Auto-generated method stub
    }

    public void stop(BundleContext context) throws Exception {
    // TODO Auto-generated method stub
    }

    }

  1. Now we need to add some output to show on the console when it runs. Change the code as shown below.

    Udpated Activator Code package com.myfirst.osgi;

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

    public class MyFirstActivator implements BundleActivator {

    public void start(BundleContext context) throws Exception {
    System.out.println("nMyFirstActivator is starting. Hello!");
    }

    public void stop(BundleContext context) throws Exception {
    System.out.println("nMyFirstActivator is stopping. Goodbye.");
    }

    }

What did you just do? In order to be able to execute your OSGi bundle stand-alone in the OSGi environment it must have a BundleActivator class that OSGi can call when it starts and stops your bundle. You must now tell OSGi about your bundle's BundleActivator class.

  1. Click on the Overview tab of the Manifests Wizard.
  2. Paste "com.myfirst.osgi.MyFirstActivator" in the Activator field.
Be sure to save the changes. Click on the MANIFEST.MF tab to see what is being stored in your bundle.

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: MyFirstOSGiProject Plug-in
Bundle-SymbolicName: MyFirstOSGiProject
Bundle-Version: 1.0.0
Bundle-Activator: com.myfirst.osgi.MyFirstActivator
Import-Package: org.osgi.framework;version="1.4.0"

You are now ready to run your bundle.

Running your OSGi Project

  1. Right click on your project and choose Run As --> OSGi Framework. A new OSGi Framework Configuration will be created and the OSGi console will open.
  2. Type "ss" on the OSGi console and you will see a list of over 500 plug-ins. We do not need all of those!
  3. Click the red X on the OSGi console to stop it (or type close). We want something much simpler.
  4. Right click again on your project and choose Run As --> Open Run Dialog.
  5. Click the New Launch Configuration icon in the upper left corner.
  6. A "New_configuration" will appear under OSGi Framework.
  7. Find the Name field in the top, center of the screen and change it to "Simple OSGi Configuration."
  8. Click the Deselect All button to deselect all the OSGi packages in the list.
  9. Re-select your project package and scroll down to the org.eclipse.osgi package and select it too.
  10. Uncheck the two check boxes below the list.
  11. Click the Apply button.

You can now click the Run button to see your OSGi bundle run. Here is the console output from my project.

Running Your OSGi Bundle osgi>
MyFirstActivator is starting. Hello.
ss

id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.1.R33x_v20070828
2 ACTIVE MyFirstOSGiProject_1.0.0

osgi> stop 2

MyFirstActivator is stopping. Goodbye.

osgi> start 2

MyFirstActivator is starting. Hello.

osgi> close

MyFirstActivator is stopping. Goodbye.

Summary

In this post you learned how to run OSGi from a command prompt as well as how to run it from within Eclipse. You also learned how to make a custom OSGi Execution Environment and pick and choose which bundles to activate. Finally, you learned about how to implement the BundleActivator interface and configure your project such that the OSGI runtime will call your BundleActivator.

In my next post we will turn our attention to deploying and running Servlets in OSGi bundles.


Steven Mitchell

View Steve Mitchell's profile on LinkedIn

8 comments:

baldeagle said...

images are not available

Steve said...

Thanks, BaldEagle, the images only worked in Firefox for some reason. I have uploaded the images to Picasa and replaced them in my blog with img tags. Thanks for letting me know.

Carlus Henry said...

Great article. I am very interested in OSGi, and this was a great introduction into how to create a bundle from scratch.

How do you run an OSGi application? For example, I want to develop a batch application, that will always be up and running. At some point, I would like to deploy new bundles and retire older ones. How do I start an application like this? Then after it is started, how do I access the OSGi console in order to do issue OSGi commands?

Thanks,
Carlus

Steve said...

Glad you liked it. I can only speak to how my client does it on my current project, as I am new to OSGi too. My code runs on an embedded Linux device. In /etc/init.d the client wrote a start-up script to launch OSGi sans console at boot-up. OSGi uses config.ini to start all the required bundles. I just had to edit the config.ini file to start the bundles that I wrote. I can telnet into the OSGi console on a specific port on the device. I have not dug into what script is running the OSGi deamon that provides telnet access to the OSGi console. I hope that answers your question.

Eric Schaffner said...

Thanks for taking the time to put together this tutorial! It's helped me bootstrap my way into the OSGi world! :-)

ulsa said...

As far as I can tell, I have followed your instructions to the letter, apart from the CDC thing. Nevertheless, it doesn't behave as yours does. My bundle starts, prints out the activator start message, and then terminates. No stop message is printed.

ouertani said...

Great blog,

I start working on osgi framework with spring DM. I fell happy to see step by step tutorial for osgi.

Go ahead!

Sellotaped to Insanity said...

Great post Steve: thx for the info.

Schoenobates