Ouertani Slim was born in Tunisia in 1981. Now he is a software engineer since 2004 and he is Java 6 and Spring certified with 100% and 94% respectively. He is very interested in Java technology, Scala and open source projects. He believes that programming is one of the hardest jobs and most beautiful in the world. Slim has posted 32 posts at DZone. You can read more from them at their website. View Full User Profile

Hessian Extender on OSGi Container

07.25.2008
| 8587 views |
  • submit to reddit

The OSGi specification 4.1 doesn't specify how to communicate between bundles inside the OSGi container and outside a Java application.

R-Osgi is not a standard, this is why I want to share a tip provided by Roman Roelofsen from Prosyst.

The first part of this post introduces the Hessian extender and its integration with Spring DM. Next, we present a simple service that communicates with a simple Java application.

Hessian Extender

Hessian is a lightweight binary protocol that needs only a simple servlet container to expose services.

To an OSGi container, Hessian acts as an extender bundle: listens to published services, extends it, and registers it on a servlet container.

We start by creating a custom tracker that acts as an abstract tracker:

package com.jtunisie.hessian.extender;

import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;

public abstract class CustomTracker extends ServiceTracker {

public CustomTracker(BundleContext context, String clazz) {
super(context, clazz, null);
}

@Override
public Object addingService(ServiceReference reference) {
try {
serviceRegistered(reference);
} catch (Exception e) {
e.printStackTrace();
}
return super.addingService(reference);
}

public abstract void serviceRegistered(ServiceReference reference) throws Exception;

@Override
public void removedService(ServiceReference reference, Object service) {
try {
serviceUnregistered(reference, service);
} catch (Exception e) {
e.printStackTrace();
}
super.removedService(reference, service);
}

public abstract void serviceUnregistered(ServiceReference reference, Object service) throws Exception;
}

 

Next , we create a listener that listens to the service, uses an inner custom tracker, and registers a servlet with the given URL:

package com.jtunisie.hessian.extender;

import com.caucho.hessian.server.HessianServlet;
import javax.servlet.Servlet;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpService;
import org.osgi.util.tracker.ServiceTracker;


public class HessianListener {

private HttpService httpService;
private ServiceTracker servletsTracker;

public HessianListener(BundleContext context) {
this.servletsTracker = new CustomTracker(context, HessianServlet.class.getName()) {

@Override
public void serviceRegistered(ServiceReference reference) throws Exception {
Servlet servlet = (Servlet) context.getService(reference);
String url = (String) reference.getProperty("url");
httpService.registerServlet(url, servlet, null, null);

}

@Override
public void serviceUnregistered(ServiceReference reference, Object service) throws Exception {
System.out.println("Unregister " + reference);
httpService.unregister((String) reference.getProperty("url"));
}
};
}

public void setHttpService(HttpService httpService) throws Exception {
this.httpService = httpService;
this.servletsTracker.open();
}

public void unsetHttpService(ServiceReference reference) {
this.servletsTracker.close();
}
}

 

We have imported com.caucho.hessian.server.HessianServlet, which we provided on the bundle class path. So, don't forget to add the Hessian library on the extender bundle.  The bundle context and httpservice will be inject by spring DM:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">

<!-- reference to HttpService -->
<osgi:reference id="httpService" interface="org.osgi.service.http.HttpService">
<osgi:listener ref="hessianListener" unbind-method="unsetHttpService" />
</osgi:reference>

<!-- configure the JettyListener -->
<bean name="hessianListener" class="com.jtunisie.hessian.extender.HessianListener">
<constructor-arg ref="bundleContext"/>
<property name="httpService" ref="httpService"/>
</bean>
</beans>

 

Published at DZone with permission of its author, Slim Ouertani.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)