Platinum Partner
java,osgi,spring dm,extender,hessian

Hessian Extender on OSGi Container

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>

 

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}