Apache Felix Event Admin
The Event Admin Service Specification, part of the OSGi Compendium specification, defines a general inter-bundle communication mechanism. The communication conforms to the popular publish/subscribe paradigm and can be performed in a synchronous or asysnchronous manner.
The main components in a publish/subscribe communication are:
- Event Publisher - sends events or messages related to a specific topic
- Event Handler (or Subscriber) - expresses interest in one or more topics and receives all the messages belonging to such topics.
Events are composed of two attributes:
- a topic defining the nature of the event; topic names are usually arranged in a hierarchical namespace, where slashes are used to separate the levels (i.e. "org/osgi/framework/FrameworkEvent/STARTED") and
- a set of properties describing the event.
Creating an Event Publisher
An event publisher is a simple Java class that creates events and sends them using the EventAdmin service interface, for example:
public void reportGenerated(Report report, BundleContext context)
{
ServiceReference ref = context.getServiceReference(EventAdmin.class.getName());
if (ref != null)
{
EventAdmin eventAdmin = (EventAdmin) context.getService(ref);
Dictionary properties = new Hashtable();
properties.put("title", report.getTitle());
properties.put("path" , report.getAbsolutePath());
properties.put("time", System.currentTimeMillis());
Event reportGeneratedEvent = new Event("com/acme/reportgenerator/GENERATED", properties);
eventAdmin.sendEvent(reportGeneratedEvent);
}
}
The EventAdmin.sendEvent() method sends the Event object synchronously. To send it asynchronously, use the EventAdmin.postEvent() method, such as:
//..
Event reportGeneratedEvent = new Event("com/acme/reportgenerator/GENERATED", properties);
eventAdmin.postEvent(reportGeneratedEvent);
Creating an Event Handler
Creating an event handler is as simple as implementing the EventHandler interface:
public class ReportEventHandler implements EventHandler { public void handleEvent(Event event) { String reportTitle = (String) event.getProperty("title"); String reportPath = (String) event.getProperty("path"); sendReportByEmail(reportTitle, reportPath); } //..
Registering an Event Handler
To receive event notifications, the event handler must be registered as a OSGi service under the object class org.osgi.service.event.EventHandler. When registering the service, a String[] property named EVENT_TOPIC must be specified; this property describes the list of topics in which the event handler is interested. For example:
String[] topics = new String[] {
"com/acme/reportgenerator/GENERATED"
};
Dictionary props = new Hashtable();
props.put(EventConstants.EVENT_TOPIC, topics);
bundleContext.registerService(EventHandler.class.getName(), new ReportEventHandler() , props);
It is possible to use '*' as a wildcard in the final character of the EVENT_TOPIC, like in this example:
String[] topics = new String[] {
"com/acme/reportgenerator/*"
};
Dictionary props = new Hashtable();
props.put(EventConstants.EVENT_TOPIC, topics);
bundleContext.registerService(EventHandler.class.getName(), new ReportEventHandler() , props);
Finally, it is possible to specify an additional EVENT_FILTER property to filter event notifications; the filter expression follows, the normal LDAP syntax:
String[] topics = new String[] {
"com/acme/reportgenerator/GENERATED"
};
Dictionary props = new Hashtable();
props.put(EventConstants.EVENT_TOPIC, topics);
props.put(EventConstants.EVENT_FILTER, "(title=samplereport)");
bundleContext.registerService(EventHandler.class.getName(), new ReportEventHandler() , props);
OSGi Events
Every OSGi framework sends (asynchronously) a number of events that can be captured by any bundle.
Framework Events
- org/osgi/framework/BundleEvent/STARTED
- org/osgi/framework/BundleEvent/ERROR
- org/osgi/framework/BundleEvent/PACKAGES_REFRESHED
- org/osgi/framework/BundleEvent/STARTLEVEL_CHANGED
- org/osgi/framework/BundleEvent/WARNING
- org/osgi/framework/BundleEvent/INFO
Bundle Events
- org/osgi/framework/BundleEvent/INSTALLED
- org/osgi/framework/BundleEvent/STARTED
- org/osgi/framework/BundleEvent/STOPPED
- org/osgi/framework/BundleEvent/UPDATED
- org/osgi/framework/BundleEvent/UNINSTALLED
- org/osgi/framework/BundleEvent/RESOLVED
- org/osgi/framework/BundleEvent/UNRESOLVED
The followig properties are always present in a bundle event object:
- bundle.id
- bundle.symbolicName
Service Events
- org/osgi/framework/ServiceEvent/REGISTERED
- org/osgi/framework/ServiceEvent/MODIFIED
- org/osgi/framework/ServiceEvent/UNREGISTERING
The following properties are always present in a service event object:
- service
- service.id
- service.pid
Each of the aforementioned events actually contains a wider set of properties. Check the OSGi Compendium specification, section 113.6, for a complete list.

