Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

OSGi 4.2: Extender Pattern and BundleTracker

DZone's Guide to

OSGi 4.2: Extender Pattern and BundleTracker

· Java Zone ·
Free Resource

Get the Edge with a Professional Java IDE. 30-day free trial.

Today I updated my dynamic OSGi demo (see screenshot below),  in particular: the extender bundle. The extender pattern is a frequently used pattern in the OSGi world. The idea is to extend the semantics of bundles by adding custom manifest headers and react, if bundles with these headers come and go dynamically. Prominent examples for using the extender pattern are service component models like OSGi Declarative Services (DS) or Spring Dynamic Modules (Spring DM). In my demo I wanted to create a simple extender that tracks bundles with the custom manifest header “Action-Contribution” and provide a class that should be registered as a service. Here an example for such a custom manifest header (you find it in the manifest of bundle com.siemens.ct.pm.ui.actions.vcard in the demo):

Action-Contribution: com.siemens.ct.pm.ui.actions.vcard.Actions

Before OSGi 4.2 I used Heiko Seeberger’s custom bundle tracker to deal with all workflow and treading issues. But since OSGi 4.2 comes with a convenient BundleTracker now, it is no longer necessary to implement all the plumbing. Here is the complete source code of my little extender:

public class ExtenderBundleTracker extends BundleTracker {

private final Logger logger = LoggerFactory
.getLogger(ExtenderBundleTracker.class);

public ExtenderBundleTracker(BundleContext context) {
super(context, Bundle.ACTIVE, null);
}

@Override
public Object addingBundle(Bundle bundle, BundleEvent event) {
String className = (String) bundle.getHeaders().get(
"Action-Contribution");
if (className != null) {
Class<?> clazz;
try {
clazz = bundle.loadClass(className);
try {
bundle.getBundleContext()
.registerService(
"com.siemens.ct.pm.application.service.IActionContribution",
clazz.newInstance(), null);
logger.info("Extender Action Contribution Service registered for: "
+ clazz.getName());

} catch (InstantiationException e) {
logger.error("Could not instantiate " + className, e);
} catch (IllegalAccessException e) {
logger.error("Illegal access during instatiation of class "
+ className, e);
}
} catch (ClassNotFoundException e) {
logger.error("Could not find class " + className, e);
}
}
return bundle;
}
}

You might wonder, why I did not overload

public void removedBundle(Bundle bundle, BundleEvent event, Object object) {}
to unregister the services. Since I used the context of the active bundle that comes in to register the service, this service is automatically unregisterd when the bundle goes away.

 

From http://www.toedter.com/blog/?p=236

Get the Java IDE that understands code & makes developing enjoyable. Level up your code with IntelliJ IDEA. Download the free trial.

Topics:

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}