OSGi EventAdmin
I recently had a few people come to me to chat about the OSGi EventAdmin service. For those who are curious, the EventAdmin
service is part of the OSGi Compendium Specification and allows you to publish and listen to events via a pub-sub system. I’ll try to do a quick write up on how to actually use the service. As with any OSGi service, the first and foremost thing you need to do is acquire the EventAdmin
service. There are many ways to do this, but I prefer to use Declarative Services these days. This is what a sample component definition would look like:
Once we acquire the EventAdmin
service, there are really two things you can do: publish and listen for events.
Publishing Events
To publish events, you need to pick a name for your topic. For example purposes, let’s pretend we wanted to publish information about memory events. A good topic name for this would be something like:
org/eclipse/equinox/events/MemoryEvent/{NORMAL,SERIOUS,CRITICAL}
If we wanted to publish a critical memory event, we have to create an Event
object and publish it using EventAdmin
:` ```java
…
Event event = new Event(“org/eclipse/equinox/events/MemoryEvent/CRITICAL”, null);
eventAdmin.postEvent(event);
` It's important to note that there are two ways of sending events using `EventAdmin`. This depends whether you want your event to be sent in a asynchronous our synchronous fashion. In the example above, we used the `postEvent(...)` method in `EventAdmin` which sends events in an asynchronous fashion. To send events in a synchronous fashion, `EventAdmin` exposes the `sendEvent(...)` method so we could simply change our code to send event synchronously:`
java
…
Event event = new Event(“org/eclipse/equinox/events/MemoryEvent/CRITICAL”, null);
eventAdmin.sendEvent(event);
``` An additional thing to note is that you can send additional properties with your events as the
Eventobject takes an optional
Map` parameter in its constructor.
Listening for Events
From the consumer side of things, we’re interested in handling the memory events. To do this, we need to register an EventHandler
, let’s call it a MemoryEventHandler
in this case:`
public class MemoryEventHandler implements EventHandler {
public void handleEvent(Event event) {
// TODO panic... handle memory event
}
}
Next, we need to register our MemoryEventHandler
with the service registry with the proper EventAdmin
topic name. There are many ways to do this, but for the variety purposes, let’s do it the traditional way in a bundle activator via a BundleContext
reference:
...
EventHandler handler = new MemoryEventHandler();
properties = new Hashtable<String, String>();
properties(
EventConstants.EVENT_TOPIC,
"org/eclipse/equinox/events/MemoryEvent/CRITICAL");
context.registerService(EventHandler.class.getName(), handler, properties);
The important part of the service registration involves topic you’re interested via the EventConstants.EVENT_TOPIC
constant. In the example above, we were interested in critical memory events so we used the proper topic:
org/eclipse/equinox/events/MemoryEvent/CRITICAL
If we were interested in all memory events, EventAdmin
supports wildcard matching on topics so we could do this:
org/eclipse/equinox/events/MemoryEvent/*
EventAdmin
also supports filtering via the EventConstants.EVENT_FILTER
constant.
For the curious, the example above could have easily been done using DS: That’s all it takes to listen for events!
EventAdmin in Eclipse
Cool, now that you know more about EventAdmin
… how about using it in your Eclipse RCP applications? Well, I have good news as Equinox has a great implementation of EventAdmin
available. Furthermore, as of Eclipse 3.6 M2, EventAdmin
will ship part of the Eclipse SDK. If you’re not building on top of Eclipse 3.6 yet, you can simply grab the event admin implementation from the Equinox SDK downloads page.
Note: The example I described in this blog is something someone proposed be included within Eclipse.