Java Message Service, 2nd Edition, by Mark Richards, covers the topic of asynchronous messaging and Java Message Service (JMS). JMS specification has a come long way since the first edition of this book was published back in 2000.
In the new book, Mark discusses the Messaging basics, common architectures used by messaging vendors and the two programming models of JMS: publish-and-subscribe and point-to-point. Advanced topics such as Messaging Filtering, Guaranteed Messaging and Transactions are also covered.
Mark discusses the Java EE implementation of messaging in EJB 3.0 specification (using Message Driven Beans) as well as Spring framework implementation of JMS messaging using Spring JMS Template and message-driven POJOs (MDPs).
The book concludes with messaging design considerations including the use of internal versus external destinations, request/reply processing, and some of the common messaging anti-patterns such as Single-Purpose Queue, Message Priority Overuse, and Message Header Misuse. The sample code examples in the book use ActiveMQ, an open source messaging container.
InfoQ spoke with Mark about his new book, the main motivation for writing it and other topics. Topics covered in the interview include the role of Spring Message Driven POJO's (MDP) in implementing messaging applications and Enterprise Service Bus (ESB) architecture.
We are also making an excerpt (314KB PDF) from the Java Message Service book available for our readers.
InfoQ: What was the main motivation in writing the 2nd edition of the book?
Mark Richards (MR): When I was asked to revise the first edition of the book, I didn't think it would be a particularly large effort, especially since the first edition of the book was so well written and so well received by the Java community (kudos to Richard Monson-Heafel and David Chappell for a great first edition). However, as I started revising the original manuscript, I quickly realized how much messaging has changed in the past 10 years since the first edition of the book was written. Not only has messaging changed from the perspective of the JMS version update (JMS 1.02 to JMS 1.1), but also in the way messaging is used. New techniques, tools, and technologies have hit the market, including Message-Driven Beans (MDB), Spring Message-Driven POJOs (MDP), enterprise-level open source providers such as ActiveMQ, RESTFul JMS interfaces, Service-Oriented Architecture, and Enterprise Service Bus middleware products. In addition, as the Java Platform matured, so did the way we use messaging. From interoperability with heterogeneous platforms and components to high-speed asynchronous concurrent processing, messaging has proven its value in most of the architectures we use today. As a result, I ended up rewriting over 75% of the book in the second edition.
My main motivation for writing the second edition of the book was a combination of my passion for technology and strong interest and experience in messaging. The opportunity presented to me allowed me to breathe new life into an already great book and help spread the word about what the JMS API is all about and how to use it to solve some very interesting problems. There is a lot of new material in the second edition, which brings this book up-to-date with how we use messaging today.
InfoQ: Spring's Message Driven POJO's (MDP) have become the design alternative to the Message Driven Beans (MDB) in EJB model. You wrote about Spring MDP's as well as the J2EE way of implementing Asynchronous Messaging, which is by using Message Driven Beans (MDB). With Spring being a full-fledge DI framework, does Spring MDP architecture offer any advantages over MDBs?
MR: Absolutely. Both the EJB and Spring frameworks support container-managed asynchronous listeners. However, the MDB architecture supported through EJB, while fairly simple and straightforward, only offers one type of asynchronous message listener. An MDB must implement the javax.jms.MessageListener interface, requiring you to implement the onMessage() method which takes as its argument a message object of type javax.jms.Message.
Spring, on the other hand, supports three types of asynchronous message listeners (MDPs). The first type of MDP matches closely with its MDB counterpart and implements the javax.jms.MessageListener interface and the corresponding onMessage() method, requiring you to process a message object of type javax.jms.Message. The second type is similar to the first, but implements a Spring framework SessionAwareMessageListener, allowing the javax.jms.Session object to be passed into the onMessage() method along with the message object, making it easy to send messages or responses after receiving them. The third type of MDP (my favorite) is a true POJO that uses a Spring MessageListenerContainer. With the third type of MDP, Spring will handle all of the message conversion automatically for you, allowing you to construct an asynchronous message listener (MDP) that has a method name like processTrade() that takes in a String argument containing some XML from the message payload rather than a non-descriptive method named onMessage() that takes a message object.
Basically, Spring MDPs remove the ceremony associated with messaging, allowing you to focus on the business logic. It is indeed cool stuff and worth a look.
InfoQ: Servlet 3.0 specification brings asynchronous communication to the web layer. What do you think the impact of Servlet 3.0 spec will have on the enterprise software development and the use cases that have some type of asynchronous processing requirements? What will this mean to the traditional asynchronous messaging programming which uses JMS technology which may not be as light-weight as the servlet model?
MR: First of all, I'm not sure I agree that the servlet model is any more light-weight than a simple messaging framework (particularly when using Spring). However, to answer your question, I do not foresee the Servlet 3 specification replacing any existing or future JMS messaging systems. Messaging offers several important aspects over the asynchronous communication aspect of the Servlet 3 specification, including superior load balancing, better monitoring capabilities, and perhaps most important, guaranteed delivery. The thing I like about the asynchronous communications aspect of the Servlet 3 specification is that it will benefit messaging in general (both JMS and non-JMS) by increasing the awareness of how important asynchronous communication is in the Java Platform, irrespective of the processing layer. However, in my opinion it will not be a replacement for the power and simplicity of JMS messaging, particularly given the ongoing efforts in the area of RESTful messaging interfaces offered by messaging providers such as WebSphere MQ and Apache ActiveMQ.
InfoQ: Where does the Enterprise Service Bus (ESB) pattern fit in the Asynchronous Messaging / JMS architecture model?
MR: An Enterprise Service Bus can communicate with consumers and producers (both internal and external) through various protocols, including HTTP and JMS. Both protocols can send and receive SOAP messages as well as plain XML (or any other message payload format for that matter). However, most ESBs are behind the firewall and serve as a messaging middleware function, providing mediation, routing, and transformation functions (to name a few). Because of this, I would argue that JMS messaging is a far better choice than web services over HTTP for many of the reasons I mentioned earlier in the interview - better reliability, less complexity, better load balancing, better monitoring, better performance, and the ability to provide guaranteed delivery.
Not surprisingly most ESBs are based on the concept of messaging, as are most other enterprise integration patterns. While most ESBs allow you to easily switch between HTTP and JMS protocols, unless your requests are coming from external Internet clients, my advice is to stick with JMS.
InfoQ: What are the best practices and "gotchas" that the developers and architects should keep in mind when working on architecting and building real-life JMS systems?
MR: My favorite "gotcha" is setting the message expiration of a message. Because the JMS API exposes the message header properties in the javax.jms.Message object through standard getters and setters, developers are often tempted to invoke the message.setJMSExpiration() directly to set the message expiration. However, the JMS provider will overwrite every message header with the exception of the JMSReplyTo, JMSCorrelationID, and sometimes the JMSType. Therefore, when you set the message expiration using the header property setter method directly, the message will in fact never expire. Instead, you need to use the setTimeToLive() method on the MessageProducer interface. The same is true with setting the message priority; invoking message.setJMSPriority() will not set the priority of the message. Instead, you need to use the setPriority() method on the MessageProducer interface.
There are many other design practices and pitfalls that developers should be aware of, such as using too few (or too many) queues, using too few (or too many) concurrent listeners, when you should use message filtering instead of multiple queues or topics, and when to use the point-to-point messaging model versus the publish-and-subscribe model. All these scenarios (and more) are covered in the new edition of the JMS book.
InfoQ: Asynchronous messaging plays an important role in Service Oriented Architecture (SOA) whether it's Event-Driven Architecture (EDA) or as a part of an ESB design. What do you see as the role of JMS in the SOA area?
MR: Services deployed within an SOA environment should be highly decoupled. They may be implemented in a variety of languages and platforms, including some that are still legacy mainframe. One of the great things about SOA is that the service implementation is completely independent of the service definition. Providing you don't change the service contract, the service implementation can be replaced and modified without the client even knowing about it. This is where messaging comes into play - what better way to decouple components and services than through messaging? Most enterprise-level commercial and open source messaging providers allow for heterogeneous communication - that is, Java sending a message to a C# or CICS component. Messaging is a critical piece of the decoupling solution within SOA.
InfoQ: What new features or changes to existing features would like to see in the future JMS specifications?
MR: The JMS 1.1 specification was released in March 2002 - over 7 years ago. That there isn't a movement to update the 1.1 specification points out that the current JMS specification is in fact very stable and very well thought out. That said, one thing I would like to see changed or added to the specification is some consistency in terms of defining subtopics within the pub/sub model. Many messaging vendors allow you to define a hierarchy of topics. For example, you may have a topic root called "ERRORS". From there, there may be two other child topics (or subtopics) off of the "ERRORS" topic defined as "ERRORS.VALIDATION" and "ERRORS.DB". These can further be broken down into the types of validation or database errors. You can define a subscriber to receive all errors by using a wildcard, such as "ERRORS.*". Or you can get all of the validation errors by subscribing to "ERRORS.VALIDATION.*. Finally, you can get all xml parsing validation errors by subscribing directly to "ERRORS.VALIDATION.XMLPARSE".
Because the JMS 1.1 specification does not define how to specifically deal with subtopics, each messaging vendor implements it differently. For example, IBM WMQ defines the separator as a slash ("/") and the wildcard as an asterisk ("*"), whereas SonicMQ uses a dot (".") for the topic separator and an asterisk ("*") for the wildcard. SwiftMQ uses a percent sign ("%") for the wildcard, and so on. It would be nice if this were standard and hence consistent across all providers.
InfoQ: Do you have any other comments or thoughts on the book and JMS topic?
MR: Only that I believe messaging (and JMS in particular) is quickly becoming a "core competency" among developers, designers, and architects. It's an exciting time for both messaging and the Java Platform. The newly released 2nd edition of the Java Message Service book will help developers come up to speed quickly in terms of understanding the JMS API and general messaging concepts.
InfoQ: Thank you Mark.