Kai is a DZone MVB and is not an employee of DZone and has posted 18 posts at DZone. View Full User Profile

OSGi 4.2: Extender Pattern and BundleTracker

07.06.2010
| 9328 views |
  • submit to reddit

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

Published at DZone with permission of Kai Tödter, author and DZone MVB.

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

Tags: