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

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

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

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}