I am a software engineer at Google on the Android project and the creator of the Java testing framework TestNG. When I'm not updating this weblog with various software-related posts or speaking at conferences, I am busy snowboarding, playing squash, tennis, golf or volleyball or scuba diving. Cedric is a DZone MVB and is not an employee of DZone and has posted 89 posts at DZone. You can read more from them at their website. View Full User Profile

Local Message Bus

07.27.2010
| 5937 views |
  • submit to reddit

Recently, I started wondering how I could improve the TestNG listener architecture.

TestNG exposes a lot of different listeners, which users can specify before starting a test run (using either of the command line, ant, Maven, testng.xml or programmatically).

These listeners tell you whenever:

  • A test succeeds, fails or is skipped.
  • A test method is about to be called and when it returns.
  • A configuration method starts or finishes (there are five types of each: suite, test, class, method and group, and you have a before and an after event for each).
  • A reporter should be notified to update its results (either at the end of the suite run or after each test methd).

All these listeners are captured by different interfaces and they have evolved somewhat organically over these past six years as the needs and requests emerged, showing some overlap in functionalities and also requiring the awkward interface evolution that Java imposes (exhibit A and exhibit B).

One possible solution to such a problem is a message (or event) bus.

Message buses have been around for a very long time and most of my PhD thesis revolved around their usage and their impact on distributed applications. I even wrote one for my PhD called Koala Talk. This was around 1993, almost twenty years ago.

The de facto standard in the Java world is the JMS specification, which has been implemented in many products such as ActiveMQ or RabbitMQ. Both the specification and implementations have been battle tested and proven to be of great usefulness for today’s software.

However, JMS is overkill for what I need to do. First of all in terms of functionalities, but also more simply because I need a local software bus, one that will always be passing messages within the same JVM. No network is necessary.

The message bus model brings a lot of simplification to a listener heavy framework such as TestNG. Instead of having to decide which interface and which method are applicable when, all TestNG needs to do is publish events as a test run is progressing. Where these events get handled and who they eventually reach is resolved outside of the TestNG engine.

Another benefit is that looking at the system in terms of events will allow to remove quite a bit of overlap. For example, in TestNG, you can be notified both when a suite finishes and when your reporter should start doing its work (generating reports). Most of the time, these events coincide.

I started sketching out what such an API could look like and I came up with the following very early draft:

public class App {

@Subscriber
public void event1(NotifyEvent ne) {
System.out.println("event1: " + ne);
}

}
MessageBus mb = new MessageBus();
mb.register(new App());
mb.post(new NotifyEvent("notify"));

Receivers describe the kind of events they are interested in and publishers simply post these events. With these ideas in mind, I started looking around to see if anything like this exists and I quickly came across EventBus, by Michael Bushe.

EventBus turns out to be remarkably close to what I had in mind, including annotation support and type based dispatching. EventBus also supports all kinds of other mechanisms, some I had in mind (string based publishing with regexp matching, event inheritance) and a few others I didn’t think of (vetos).

EventBus seems to be very extensive, very well designed and tested (nice job, Michael!), but probably too big for what I need. It also contains quite a few ties to Swing because it apparently started as a support library for Swing applications that publish events (something that Swing developers have to deal with all the time). Admittedly, there is a portion of EventBus that seems to be graphic independent, but I haven’t been able to really understand its full extent and whether it’s possible to carve it out at all (I have no interest in dragging in Swing dependencies).

Interestingly, it’s the only library of that type that I was able to find, so before I dig further, has anyone heard of a framework allowing the kind of simple intra JVM publish/subscribe functionality I’m looking for?

 

From http://beust.com/weblog/2010/07/26/local-message-bus/

Published at DZone with permission of Cedric Beust, 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:

Comments

Aravind Yarram replied on Tue, 2010/07/27 - 4:01am

http://code.google.com/p/mycila/#Mycila_Event

Sudhakar Ramasamy replied on Tue, 2010/07/27 - 5:58am

ZeroMQ (http://www.zeromq.org/) appears to be a lightweight messaging solution, but may still be too heavy weight for what you need. I came across it a few days ago and have absolutely no experience using it. Just thought I'd throw it in here in case someone has experience with it.

Fabrizio Giudici replied on Tue, 2010/07/27 - 1:35pm

You can use the very small EventBus designed for the NetBeans Platform. It's a very thin piece of code and only depends on the simpler module of the NetBeans Platform (org-openide-util). Indeed, since the recent release of NetBeans 6.9, the thing can be made to depend on a new split, smaller module (org-openide-lookup), which has removed a lot of useless dependencies and AFAIK (I haven't upgraded to it yet) it shouldn't be depending on Swing stuff. Please let us know whether you like it or not (and why). Thanks.

PS For the record, if you aren't acquainted with the NetBeans Platform, don't worry about the .nbm modules. In the Maven repository you can depend on plain .jar as well.

Tom Schindl replied on Tue, 2010/08/03 - 1:52am

When running on OSGi you could use the org.osgi.service.event.EventAdmin. e4 for example uses this as the underlying implementation of its event system.

Dave Joyce replied on Mon, 2010/09/27 - 11:40pm in response to: Tom Schindl

Tom, this is exactly what I'm aiming to create: an event bus architecture on OSGi. My intent is to create adapter bundles that would forward events from the JVM or BundleContext over some other protocol (JMS, XMPP, etc.)

Do you have any links you could share to clarify use of EventAdmin as an event bus? Thanks!

Rehman Khan replied on Sat, 2012/02/25 - 3:51am

Google Web Toolkit has an implementation of Event Bus. Not quite sure if it is what you are looking for (since it is targeted for JavaScript and doesn’t have annotation support or fancy dispatching) but it is type-safe and easy to use. Just thought you might be interested to take a look at it.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.