My Stuff

2010 Conferences

OSGi DevCon @ JAX London

February 23 - Keynote titled OSGi in the Enterprise: Agility, Modularity, and Architecture’s Paradox

EclipseCon

March 22 - 25 - Tutorial on Modular Architecture

Über Conf

June 14 - 17 - Sessions titled Turtles and Architecture and Patterns of Modular Architecture

Catalyst

July 26 - 30 - Two sessions on rich mobile applications and one on agile development. Half day tutorial on software process improvement.

Tweets @ Twitter

re: #apple event "We sold more iPads than any PC manufacturer sold of their entire PC line." 2012-09-12

re: #Apple Event ""Our notebooks now rank #1 in the US in Market share in the last three months." 2012-09-12

Right on. I just won a Best Buy drawing worth $1000. Either that or I won a shiny new virus by clicking the link. Hmm...what to do. 2012-08-29

The #osgi alliance response (http://t.co/KrN8XNWg) to the @mreinhold #jigsaw announcement (http://t.co/9YvcDdqC). 2012-08-29

Good Q&A with @mreinhold on project #jigsaw. http://t.co/9YvcDdqC. Modularity will change the way we design and run apps! 2012-08-28

LinkedIn Profile

The opinions expressed on this site are my own, and not necessarily those of my employer.

Simple OSGi Service

Filed Under Architecture & Design, Java, OSGi, Platforms |  

Lately, I’ve been experimenting more with OSGi, and I want to share some of the examples I’ve put together. The examples involve Felix, Spring Dynamic Modules, and Jetty, though could easily be used with Equinox. Once I’m finished with these exercises, I’m hoping to compare and contrast the different approaches I’ve taken, as well as comparing embedded Jetty with the Equinox Servlet Bridge. I’m a believer that OSGi is a disruptive technology that stands to transform Java development as we know it today.

There are numerous OSGi tutorials, blogs, and samples posted around the web. My OSGi resources page lists some of these, and if you know of other good resources not listed, please let me know. When I experiment with a new technology, I like to focus exclusively on the technology itself, without code generators, wizards, or other utilities that do half the work for me. I feel it maximizes the experience. To that end, all of my exercises avoid using tools like Maven or Eclipse. I find Maven confusing and using Eclipse for some of these smaller exercises is overkill. Save for a few necessary tools like Ant and the Felix framework itself, I’ll roll everything by hand. Hopefully, this helps clarify the core essence of OSGi.

The first sample is the canonical HelloWorld example where I create two simple bundles - a client.jar and service.jar. Again, in OSGi parlance, a bundle is a .jar file. You can find the working code in My Google Code repository (the HelloWorld project), complete with the Ant build script, the bundle cache, and a .bat or .sh script to start Felix depending on your OS. The only two prerequisites for these samples is Felix (I used version 1.0.0) and Ant, which you’ll have to download separately. Let’s walk through the creation of these two simple bundles.

First, let’s look at HelloConsumer in client.jar. HelloConsumer uses the HelloService to get the hello and goodbye messages when the client.jar bundle is started and stopped, respectively. HelloConsumer implements OSGi’s BundleActivator, meaning Felix will invoke the start method when the bundle is started, and the stop method when the bundle is stopped. As seen on line 26, HelloConsumer obtains a reference to the HelloService using the OSGi ServiceTracker class.

The HelloService and HelloServiceImpl form the OSGi service. HelloService is a simple Java interface that defines the API, while HelloServiceImpl implements the BundleActivator and is the class invoked when the server bundle is started and stopped. As seen on line 18, HelloServiceImpl registers itself as an OSGi service. Without registration, HelloConsumer would not be able to use HelloService as an OSGi service.

There’s a bit more magic here that makes this all work. A wonderful aspect of OSGi is that dependencies must be managed explicitly, with each bundle’s manifest declaring the packages the bundle imports and exports. Bundle manifests specify other key pieces of information, too. Notably, it tells the OSGi environment of the BundleActivator to invoke on start and stop. If a bundle imports a package, then another bundle within that OSGi run-time must export that same package. The client bundle manifest imports the package containing HelloService while the service bundle manifest exports that same package. Were these imports and exports not explicitly declared, we’d receive OSGi run-time errors. In our example above, HelloServiceImpl registers itself as an OSGi service allowing clients to obtain a reference to HelloService using the OSGi ServiceTracker.

The client and service OSGi bundles can be deployed to any OSGi run-time. I’ve used Felix for this example, but could have used Equinox just as easily. To run these examples, you can checkout the code from the Google Code repository. Since I include the bundle cache in the repository, you should be able to start felix and experiment with OSGi. You’ll likely have to modify the start script (OS-based) to ensure Felix is in your classpath. Upon starting Felix, you’ll be asked to enter a profile name. To use the bundle cache included with the example, simply use HelloWorld as your profile.

If you’re feeling a bit more adventurous, you can make some changes to the HelloServiceImpl message and rebuild the project by invoking the Ant build script. Once compiled, move back into the Felix shell and update the service bundle using the Felix update command. For a listing of all Felix commands, simply type ‘help’.

If you want to deploy the bundles to your own Felix cache, restart Felix and enter a different profile name. Any name will do, and Felix will create a new bundle cache for you. Here are some more suggested steps to build, install, and continue experimenting with the bundles and OSGi:

  • Build service by executing ant within service directory
  • Build client by executing ant within client directory
  • Run startfelix.bat or startfelix.sh depending on your OS
  • install the bundles from the felix shell
    • install file:service/bin/service.jar
    • install file:client/bin/client.jar
    • ps
    • start {service-bundle-id}
    • start {client-bundle-id}
  • Experiment by starting and stopping client and service to get a feel for OSGi.
  • Now change the service message printed in HelloServiceImpl.java and compile. Then do the following while client is running.
    • stop {service-bundle-id}
    • update {service-bundle-id}
    • start {service-bundle-id}
    • stop {client-bundle-id}

When stopping the client bundle, you should see a different goodbye message than what you saw in step 4.

OSGi offers a very dynamic and adaptable run-time environment. Even when not using OSGi services, reuse across bundles can occur so long as the package dependencies are explicitly managed in the bundle manifests. The benefit with OSGi services is that the OSGi run-time manages the service lifecycle, however. Many of the presentations I give on architecture & design talk about the importance of managing .jar relationships, and I’ve long felt that the .jar file is a great candidate as a first class component on the Java platform. In the next post, I’ll explore the simple benefits of an incredibly important heuristic that states we should “separate interface from implementation.” You can get a head start by taking a look at the HelloWorldSpec project on My Google Code repository.

Comments

6 Responses to “Simple OSGi Service”

  1. My OSGi Learning Path (Part 1) on May 8th, 2008 6:38 pm

    [...] The first one introduces the notion of a service in OSGi [...]

  2. OSGi and Embedded Jetty : Software & Technology @kirkk.com on February 2nd, 2009 5:52 pm

    [...] to embed Jetty, the application server, into Felix, the OSGi runtime. As with my previous posts (Simple OSGi Service, OSGi & Modularity, and OSGi & Spring), I’m trying to use the simplest tools for the [...]

  3. Short tutorials on OSGi, Spring OSGi services and Jetty OSGi « The OSGi Look on February 6th, 2009 6:08 am

    [...] OSGi tutorials Simple OSGi service OSGi & [...]

  4. nWizard - Norbert Rakosi’s blog on Free Software development … JAVA … Personal Development… and … bad speling… » OSGi…on and on… on February 20th, 2009 2:31 pm

    [...] Simple OSGi Service - The simplest OSGi service just to show the basics of OSGi. A good “getting started” guide if you’re not familar with OSGi. [...]

  5. vijayabaskar on April 29th, 2009 7:58 am

    Hi da i solved the classloader problem now its working good but if v create two servlet container named sample1 and sample2

    example:
    i have created two servlet container named sample1 and sample2
    i had created same package name for both.

    In sample1,
    i created one servlet class with package name like com.sample.Hellowrold and /hello1 is alias name

    In sample2,
    i created one servlet class like com.sample.Hellowrold and /hello2 is alias name.

    i need to register the servlet in registerServlet method.
    it takes only the first class name.

    pls help me to define the registerServlet for this.

    see below code in mainThread class

    hs = (HttpServlet) cls.newInstance();
    System.out.println(”war : “+wars[i]+” context:”+contexts[j][0]);

    httpService.registerServlet(wars[i]+contexts[j][0],hs, null,null);

    output:

    war : /sample1 context:/hello
    hs : /sample1 com.sample.HelloWorld@16ba008

    war : /sample2 context:/hello
    hs : /sample2 com.sample.HelloWorld@@9f2cff

    sample1 only work..
    pls help me to solve this problem..

  6. Lahiru Gunathilake on November 20th, 2009 1:17 pm

    In your example in the consumer can we use bundlecontext only to get the service reference rather using a ServiceTracker.. simply calling getServiceReference method by parsing the class.getName() of HelloService class?

    Is this possible? If yes what is the usage of ServiceTracker?

    BTW cool articles thanks !

    Lahiru

Leave a Reply