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

Learn how to stop testing everything every sprint and only test the code you’ve changed. Brought to you by Parasoft.

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 top tips for Java developers and best practices to overcome common challenges. Brought to you by Parasoft.

Topics:

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}