JBoss.orgCommunity Documentation

Chapter 8. Provided Examples

8.1. Build and Run the Examples
8.2. Event Admin Example
8.3. Blueprint Container
8.4. HttpService
8.5. JAXB Service
8.6. JMX Service
8.7. JNDI Service
8.8. JTA Service
8.9. Lifecycle Interceptor
8.10. Microcontainer Service
8.11. Web Application
8.12. ServiceLoader Example
8.13. XML Parser Service
8.14. XML Unmarshaller Service

JBoss OSGi comes with a number of examples that demonstrate supported functionality and show best practices. All examples are part of the binary distribution and tightly integrated in our Maven Build Process and Hudson QA Environment.

The examples can be either run against an embedded OSGi framework or against the remote OSGi Runtime. Here is how you build and run the against the embedded framework.

[tdiesler@tddell example]$ mvn test
 T E S T S
Running org.jboss.test.osgi.example.webapp.WebAppInterceptorTestCase
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 14.417 sec

Tests run: 25, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 minute 31 seconds
[INFO] Finished at: Tue Dec 08 11:15:08 CET 2009
[INFO] Final Memory: 35M/139M
[INFO] ------------------------------------------------------------------------

To run the examples against a remote OSGi Runtime, you need to provide the target container that the runtime should connect to. This can be done with the target.container system property.

    mvn -Dtarget.container=runtime test

Suported target container values are:

  • runtime
  • jboss501
  • jboss510
  • jboss600
  • jboss601

To run the examples against a different OSGi Framework, you need to define the framework system property.

    mvn -Dframework=felix test

Suported framework values are:

  • jbossmc
  • equinox
  • felix

The example-event.jar bundle uses the EventAdmin service to send/receive events.

public void testEventHandler() throws Exception
  TestEventHandler eventHandler = new TestEventHandler();
  // Register the EventHandler
  Dictionary param = new Hashtable();
  param.put(EventConstants.EVENT_TOPIC, new String[] { TOPIC });
  context.registerService(EventHandler.class.getName(), eventHandler, param);
  // Send event through the the EventAdmin
  ServiceReference sref = context.getServiceReference(EventAdmin.class.getName());
  EventAdmin eventAdmin = (EventAdmin)context.getService(sref);
  eventAdmin.sendEvent(new Event(TOPIC, null));
  // Verify received event
  assertEquals("Event received", 1, eventHandler.received.size());
  assertEquals(TOPIC, eventHandler.received.get(0).getTopic());

The example-blueprint.jar bundle contains a number of components that are wired together and registerd as OSGi service through the Blueprint Container Service.

The example uses this simple blueprint descriptor

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" ...>
  <bean id="beanA" class="org.jboss.test.osgi.example.blueprint.bundle.BeanA">
    <property name="mbeanServer" ref="mbeanService"/>
  <service id="serviceA" ref="beanA" interface="org.jboss.test.osgi.example.blueprint.bundle.ServiceA">
  <service id="serviceB" interface="org.jboss.test.osgi.example.blueprint.bundle.ServiceB">
    <bean class="org.jboss.test.osgi.example.blueprint.bundle.BeanB">
       <property name="beanA" ref="beanA"/>
  <reference id="mbeanService" interface="javax.management.MBeanServer"/>


The Blueprint Container registers two services ServiceA and ServiceB. ServiceA is backed up by BeanA, ServiceB is backed up by the anonymous BeanB. BeanA is injected into BeanB and the MBeanServer gets injected into BeanA. Both beans are plain POJOs. There is no BundleActivator neccessary to register the services.

The example test verifies the correct wiring like this

public void testServiceA() throws Exception
  ServiceReference sref = context.getServiceReference(ServiceA.class.getName());
  assertNotNull("ServiceA not null", sref);
  ServiceA service = (ServiceA)context.getService(sref);
  MBeanServer mbeanServer = service.getMbeanServer();
  assertNotNull("MBeanServer not null", mbeanServer);

public void testServiceB() throws Exception
  ServiceReference sref = context.getServiceReference(ServiceB.class.getName());
  assertNotNull("ServiceB not null", sref);
  ServiceB service = (ServiceB)context.getService(sref);
  BeanA beanA = service.getBeanA();
  assertNotNull("BeanA not null", beanA);

The example-http.jar bundle contains a Service that registeres a servlet and a resource with the HttpService.

ServiceTracker tracker = new ServiceTracker(context, HttpService.class.getName(), null);
HttpService httpService = (HttpService)tracker.getService();
if (httpService == null)
   throw new IllegalStateException("HttpService not registered");
Properties initParams = new Properties();
initParams.setProperty("initProp", "SomeValue");
httpService.registerServlet("/servlet", new EndpointServlet(context), initParams, null);
httpService.registerResources("/file", "/res", null);

The test then verifies that the registered servlet context and the registered resource can be accessed.

The example-xml-jaxb.jar bundle gets the JAXBContext from the JAXBService and unmarshalls an XML document using JAXB

ServiceReference sref = context.getServiceReference(JAXBService.class.getName());
if (sref == null)
   throw new IllegalStateException("JAXBService not available");
JAXBService service = (JAXBService)context.getService(sref);
JAXBContext jaxbContext = service.newJAXBContext(getClass().getPackage().getName());
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
URL resURL = context.getBundle().getResource("booking.xml");
JAXBElement rootElement = unmarshaller.unmarshal(resURL.openStream());
assertNotNull("root element not null", rootElement);

The example-jmx.jar bundle tracks the MBeanServer service and registers a pojo with JMX. It then verifies the JMX access.

public class FooServiceActivator implements BundleActivator
   public void start(BundleContext context)
      ServiceTracker tracker = new ServiceTracker(context, MBeanServer.class.getName(), null)
         public Object addingService(ServiceReference reference)
            MBeanServer mbeanServer = (MBeanServer)super.addingService(reference);
            return mbeanServer;
         public void removedService(ServiceReference reference, Object service)
            super.removedService(reference, service);
   public void stop(BundleContext context)
      ServiceReference sref = context.getServiceReference(MBeanServer.class.getName());
      if (sref != null)
         MBeanServer mbeanServer = (MBeanServer)context.getService(sref);

public void testMBeanAccess() throws Exception
  FooMBean foo = (FooMBean)MBeanProxy.get(FooMBean.class, MBEAN_NAME, runtime.getMBeanServer());
  assertEquals("hello", foo.echo("hello"));

The example-jndi.jar bundle gets the InitialContext service and registers a string with JNDI. It then verifies the JNDI access.

ServiceReference sref = context.getServiceReference(InitialContext.class.getName());
if (sref == null)
   throw new IllegalStateException("Cannot access the InitialContext");
InitialContext iniContext = (InitialContext)context.getService(sref);
iniCtx.createSubcontext("test").bind("Foo", new String("Bar"));

public void testJNDIAccess() throws Exception
  InitialContext iniCtx = runtime.getInitialContext();
  String lookup = (String)iniCtx.lookup("test/Foo");
  assertEquals("JNDI bound String expected", "Bar", lookup);
  // Uninstall should unbind the object
     fail("NameNotFoundException expected");
  catch (NameNotFoundException ex)
     // expected

The example-jta.jar bundle gets the javax.transaction.UserTransaction service and registers a transactional user object (i.e. one that implements Synchronization) with the javax.transaction.TransactionManager service. It then verifies that modifications on the user object are transactional.

Transactional txObj = new Transactional();
ServiceReference userTxRef = context.getServiceReference(UserTransaction.class.getName());
assertNotNull("UserTransaction service not null", userTxRef);
UserTransaction userTx = (UserTransaction)context.getService(userTxRef);
assertNotNull("UserTransaction not null", userTx);
   ServiceReference tmRef = context.getServiceReference(TransactionManager.class.getName());
   assertNotNull("TransactionManager service not null", tmRef);
   TransactionManager tm = (TransactionManager)context.getService(tmRef);
   assertNotNull("TransactionManager not null", tm);
   Transaction tx = tm.getTransaction();
   assertNotNull("Transaction not null", tx);
   txObj.setMessage("Donate $1.000.000");
   assertNull("Uncommited message null", txObj.getMessage());
catch (Exception e)
assertEquals("Donate $1.000.000", txObj.getMessage());

class Transactional implements Synchronization
  public void afterCompletion(int status)
     if (status == Status.STATUS_COMMITTED)
        message = volatileMessage;

The interceptor example deployes a bundle that contains some metadata and an interceptor bundle that processes the metadata and registeres an http endpoint from it. The idea is that the bundle does not process its own metadata. Instead this work is delegated to some specialized metadata processor (i.e. the interceptor).

Each interceptor is itself registered as a service. This is the well known Whiteboard Pattern.

public class InterceptorActivator implements BundleActivator
   public void start(BundleContext context)
      LifecycleInterceptor publisher = new PublisherInterceptor();
      LifecycleInterceptor parser = new ParserInterceptor();
      // Add the interceptors, the order of which is handles by the service
      context.registerService(LifecycleInterceptor.class.getName(), publisher, null);
      context.registerService(LifecycleInterceptor.class.getName(), parser, null);

public class ParserInterceptor extends AbstractLifecycleInterceptor
      // Add the provided output
   public void invoke(int state, InvocationContext context)
      // Do nothing if the metadata is already available  
      HttpMetadata metadata = context.getAttachment(HttpMetadata.class);
      if (metadata != null)
      // Parse and create metadta on STARTING
      if (state == Bundle.STARTING)
          VirtualFile root = context.getRoot();
          VirtualFile propsFile = root.getChild("/http-metadata.properties");
          if (propsFile != null)
             log.info("Create and attach HttpMetadata");
             metadata = createHttpMetadata(propsFile);
             context.addAttachment(HttpMetadata.class, metadata);

public class PublisherInterceptor extends AbstractLifecycleInterceptor
      // Add the required input
   public void invoke(int state, InvocationContext context)
      // HttpMetadata is guaratied to be available because we registered
      // this type as required input
      HttpMetadata metadata = context.getAttachment(HttpMetadata.class);
      // Register HttpMetadata on STARTING 
      if (state == Bundle.STARTING)
         String servletName = metadata.getServletName();
         // Load the endpoint servlet from the bundle
         Bundle bundle = context.getBundle();
         Class servletClass = bundle.loadClass(servletName);
         HttpServlet servlet = (HttpServlet)servletClass.newInstance();
         // Register the servlet with the HttpService
         HttpService httpService = getHttpService(context, true);
         httpService.registerServlet("/servlet", servlet, null, null);
      // Unregister the endpoint on STOPPING 
      else if (state == Bundle.STOPPING)
         log.info("Unpublish HttpMetadata: " + metadata);
         HttpService httpService = getHttpService(context, false);
         if (httpService != null)

The example-microcontainer.jar bundle calls a service from an MC bean and vica versa. The MC bean gets the MBeanServer injected and registeres itself as an MBean.

The test accesses the registered MBean.

public void testServiceRoundTrip() throws Exception
  SomeBeanMBean someBean = MBeanProxy.get(SomeBeanMBean.class, MBEAN_NAME, runtime.getMBeanServer());
  assertEquals("hello", someBean.echo("hello"));
  assertEquals("hello", someBean.callSomeService("hello"));

The example-webapp.war archive is an OSGi Bundle and a Web Application Archive (WAR) at the same time. Similar to HTTP Service Example it registers a servlet and resources with the WebApp container. This is done through a standard web.xml descriptor.

<web-app xmlns="http://java.sun.com/xml/ns/javaee" ... version="2.5">

  <display-name>WebApp Sample</display-name>




The associated OSGi manifest looks like this.

Manifest-Version: 1.0
Bundle-Name: example-webapp
Bundle-ManifestVersion: 2
Bundle-SymbolicName: example-webapp
Bundle-ClassPath: .,WEB-INF/classes
Import-Package: org.osgi.service.http,org.ops4j.pax.web.service,javax.servlet,javax.servlet.http

The test verifies that we can access the servlet and some resources.

public void testResourceAccess() throws Exception
  assertEquals("Hello from Resource", getHttpResponse("/message.txt"));
public void testServletAccess() throws Exception
  assertEquals("Hello from Servlet", getHttpResponse("/servlet?test=plain"));

The ServiceLoader example uses three bundles - example-serviceloader-api.jar, example-serviceloader-impl.jar, example-serviceloader-client.jar. The implementation bundle contains a traditional service defined in META-INF/services. This service definition gets picked up by the ServiceLoader Interceptor and is automatically registered with the OSGi Framework.

For details and more background information, please hava a look at ServiceLoader and how it relates to OSGi.

The example-xml-parser.jar bundle gets a DocumentBuilderFactory/SAXParserFactory respectivly and unmarshalls an XML document using that parser.

ServiceReference sref = context.getServiceReference(DocumentBuilderFactory.class.getName());
if (sref == null)
   throw new IllegalStateException("DocumentBuilderFactory not available");
DocumentBuilderFactory factory = (DocumentBuilderFactory)context.getService(sref);
DocumentBuilder domBuilder = factory.newDocumentBuilder();
URL resURL = context.getBundle().getResource("example-xml-parser.xml");
Document dom = domBuilder.parse(resURL.openStream());
assertNotNull("Document not null", dom);

ServiceReference sref = context.getServiceReference(SAXParserFactory.class.getName());
if (sref == null)
   throw new IllegalStateException("SAXParserFactory not available");
SAXParserFactory factory = (SAXParserFactory)context.getService(sref);
SAXParser saxParser = factory.newSAXParser();
URL resURL = context.getBundle().getResource("example-xml-parser.xml");
SAXHandler saxHandler = new SAXHandler();
saxParser.parse(resURL.openStream(), saxHandler);
assertEquals("content", saxHandler.getContent());

The example-xml-binding.jar bundle unmarshalls an XML document through the UnmarshallerService. This example is very similar to the JAXB Example. However, it uses JBossXB to do the unmarshalling.

ServiceReference sref = context.getServiceReference(UnmarshallerService.class.getName());
UnmarshallerService unmarshaller = (UnmarshallerService)context.getService(sref);
Bundle bundle = context.getBundle();
URL xsdurl = bundle.getEntry("booking.xsd");
URL xmlurl = bundle.getEntry("booking.xml");
unmarshaller.registerSchemaLocation("http://org.jboss.test.osgi.jbossxb.simple/booking.xsd", xsdurl.toExternalForm());
unmarshaller.addClassBinding(CourseBooking.NAMESPACE_XML_SIMPLE, CourseBooking.class);
CourseBooking booking = (CourseBooking)unmarshaller.unmarshal(xmlurl.toExternalForm());