The Source for Java Technology Collaboration
User: Password:



David Walend's Blog

Distributed Archives


SalutafugiJMS -- Java Messaging Service on ZeroConf

Posted by dwalend on June 24, 2007 at 09:34 AM | Permalink | Comments (5)

SalutafugiJMS is a peer-to-peer implementation of the Java Messaging Service specification that uses ZeroConf DNS-SD discovery and TCP sockets to communicate in a distributed computing system. I built it after seeing Daniel Steinberg's JavaOne talk on ZeroConf. SalutafugiJMS uses SomnifugiJMS as a skeleton and Apple's Bonjour implementation of ZeroConf for muscle inside special SomnifugiJMS FanOuts and Channels. SalutafugiJMS eliminates the central (or federated or clustered) message broker found in traditional JMS implementations and the need to manage specific services required by traditional DNS-SD systems. Name the JMS Queues and Topics for information your system needs to exchange. Your system consumes what your system needs. Your system sends out what it chooses. SalutafugiJMS takes care of the rest, leaving your system very loosely coupled.

Broker-Free JMS

In a traditional JMS application, message producers and message consumers don't have to know about each other. That feature creates highly decoupled systems. However, message producers and consumers all have to get connections to the same JMS message broker. That shared knowledge about the JMS broker usually comes from magic connection url strings to summon objects out of JNDI servers. Getting those magic strings correct is tedious; many elaborate projects focus on abstracting away those strings, sometimes to the point of programming in XML. SalutafugiJMS is a peer-to-peer system -- producers send messages directly to consumers -- while remaining highly decoupled. The only magic string for you to wrangle is the name of the JMS Topic or Queue. No central broker exists; the system can handle failures in any single service and keep going.

Anonymous ZeroConf

In a traditional ZeroConf system, ZeroConf provides service discovery; a service registers itself so that applications can discover and use it. Those applications browse for the services they need, and resolve them by name. The system is loosely coupled at build time, but becomes very tightly coupled as soon as the application resolves the services at runtime. If the application depends on a service that fails midway through a run, that application suffers. SalutafugiJMS adds JMS' anonymous endpoints to ZeroConf to eliminate that tight coupling. Behind the curtain, SalutafugiJMS consumers register what Queue or Topic they wish to receive messages from. SalutafugiJMS manages browsing and resolving the services inside the producers. Your applications simply produce and consume messages in the system when they need to.

Building SalutafugiJMS

I spent about thirty hours' total reading, designing and coding to get messages flowing between JMS Topic Publishers and Subscribers. Bonjour's programmers' interface is a little call-back heavy. Stopping all the services' monitor threads took some thought and a little reworking of SomnifugiJMS. Daniel and Stuart Cheshire's book was very good; everything worked like they said it would. Getting to the initial release was easy and fun. I'd hoped to be able to mine the effort for half-a-dozen blogs, but I think I'll only get two -- one on Thread.sleep(), and one comparing ZeroConf, JXTA and JINI.

The only aggravating part was getting the Bonjour dns_sd.jar from Apple. I do most of my work on an older G4 Mac (amazingly long battery life). Apple's Bonjour page provided a windows .exe installer to get at that dns_sd.jar. I got the jar from a friend with a newer Intel Mac. Daniel tells me I could have pulled in the Bonjour source code and built the dns_sd.jar myself after all. I've gotten very used to Java's jar-based library distribution. I normally only pull in source code to help fix problems and add features. I didn't even think to look.

SalutafugiJMS' first release is very much alpha-0-1, JMS Topics-only, and missing many features. SalutafugiJMS seems a little slow and I haven't looked into why. I haven't used SalutafugiJMS in any of my own applications yet, so downloader beware. Alpha-0-2 will focus on logging and fault management, alpha-0-3 on filling in features for Topics.

If you're more interested in broker-free JMS now and can swallow a GPL (or maybe MPL) license, have a look at MantaRay. I think they use a proprietary multicast protocol, not ZeroConf. They've had a working peer-to-peer JMS for a few years.



SomnifugiJMS for User Interfaces and Simple-Enough APIs

Posted by dwalend on September 11, 2003 at 04:56 AM | Permalink | Comments (2)

Somnifugi JMS is an implementation of the Java Messaging Service built on top of Doug Lea's Channels. This JMS implementation runs inside a single JVM, quickly delivering messages between java Threads. A few years back, I created Somnifugi JMS to speed up a project where the architects had gone overboard with messaging. I used Somnifugi JMS to prototype and test the next project, and left it in place to keep things fast. The project after that, I used a Somnifugi JMS Topic to communicate from the AWT Thread to other Threads where the controllers and models live. It worked great; I've used it in every Swing project since then, and a few others have started using it this way, too.

I have trouble tracking all the issues in building a Swing interface: Swing's API has about a hundred top-level classes, each with a few dozen methods, plus nine subpackages, AWT, and Java2D to get things just right. Getting a group of people to all use MVC, JavaBeans and Threads the same way is hard. The model always has its own dynamics, and usually changes a few times a day. Add users unfamiliar with the new UI to make the project even harder.

The "Use Topics to communicate from the view to the controllers" pattern is a nice complement to the "Use SwingUtils.invokeLater() to communicate from the controllers to the view" pattern. Extending the pattern to place model handling in separate Threads is just a matter of adding extra Topics or Queues for the controller to consume. Plus if I need to make the application fit a client-server model, all I have to do is swap the model's Somnifugi JMS Topics for distributed JMS Topics.

I think the power in this pattern comes from breaking up the task into small, easy-to-grasp pieces.

Using a Topic to communicate from the view to the controller simplifies both by decoupling them. The view generates messages whenever any user action happens. The controller digests those messages. The JMS API is small and easy to learn and use. Using Topics simplifies performance decisions about handling Threads and shared Objects. The projects become more predictable, easier to decouple and test, and more pleasant to work on.

I think a lot of this gain is because a JMS Topic is easier to use than Java's threading support. The JMS specification is one of the best written specifications to come out of the JCP. The underlying ideas work without bending the universe to match. Each interface fills an outlined role and I don't have to do anything weird to my own code to use them. There's no requiring me to inheriting from someone else's superclass for example. (See Allen Holub's article, "The fragile base-class problem".) I needed a single afternoon to read the spec, and I understood without strain.

I spoke briefly with Joseph Fialli (one of the authors of the JMS spec) after he gave an invited talk (on JaxB) at a local user group. I described how I was using JMS behind Swing interfaces. He thought the pattern was pretty slick. He was the only person ever to compare it to InfoBus.* After the talk, I found my notes from reading the InfoBus spec in 1999. "InfoBus API looks more complex than just using the Thread API. We'd need to fill in most of the JavaBeans event spec. Not a good fit for our problem." Over the years, I've never seen a project that uses InfoBus, despite the hype it received in the late 90's. A JSR to update the InfoBus specification was started in 1998 but withdrawn in 1999. I think the InfoBus spec has been abandoned, but some ideas live on in the JavaBeans spec.

I think there's a strong correlation between simple APIs and how likely developers are to use those APIs. JMS survives and thrives because it meets a need that developers recognize with relatively little overhead. JMS exemplifies a "Simple-Enough Principle" for API design. Developers never adopted InfoBus in large numbers because we didn't think InfoBus was any better than what we had before.

Because all the code I write becomes library code, I try to keep this principle in mind when I define APIs. I want to create an API rich enough to do the job, but simple enough for another developer to be able to use without expanding the problem he's working on. Perhaps the advances in Aspect-Oriented code will reduce the typing overhead for JavaBeans to the point where developers can meet the specification. But that's a different blog.

* As I added mark up to this article, I got email from Ted Shab asking about Somnifugi JMS, "We are looking for InfoBus-like functionality, as well as some other related concepts."



Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds