Last night, I attended the New England Java Users Group to see Mark Fisher talk about Message Driven POJOs. This was the first JUG I've been to (outside of Denver's) where I was an attendee instead of a speaker. It was interesting to see how they do things. They have one main speaker who speaks for two hours. After the first hour, they have a break, offer pizza and do a raffle. Then the speaker continues. They require you to "register" at least 48 hours before the meeting starts. This is because the meeting is held at Sun and they (apparently) need to do it for security purposes. They actually checked my ID and made sure I was registered at the door. After I passed their verification test, I received a name tag. While I like Denver's Basic Concepts followed by Main Speaker setup, I liked that this JUG meeting was over at 8:15. Below are my notes from the event.
Topics in this Session: Overview of JMS, Spring's JmsTemplate and implementing a Message Driven POJO.
Goals of JMS: provide a vendor-neutral abstraction for accessing Message Oriented Middleware from Java. It provides for enterprise messaging systems what JDBC provides for relational databases. See Wikipedia's definition of JMS for more information.
The API is what insulates your code from the JMS implementation you're using. The JMS implementation will use a message broker to communicate between servers. Tonight, Mark will be using ActiveMQ in his examples. He plans on doing most of his presentation in Eclipse because he's been spending 14 hours per day in PowerPoint revamping Interface21's training courses (I don't miss that at all).
The JMS Message is the central object to JMS. There's various types of messages, TextMessage, ObjectMessage (I missed the rest). Two types of JMS Destinations are available: Queues and Topics. A JMS Session is used to create messages as well as producers and consumers. Examples calls:
A JMS Connection is obtained from a JMS ConnectionFactory. The ConnectionFactory is typically accessed by a JNDI Lookup.
JMS is most commonly used for internal application communications (not public facing).
Templates are common in the Spring Framework and are used to simply API usage. Their main goal is to reduce boilerplate code (resource management, try/catch, etc.). Examples include JdbcTemplate, JpaTemplate, JndiTemplate, TransactionTemplate and (you guessed it) JmsTemplate. Spring also translates exceptions to consistent runtime hierarchies. In addition to one-line methods, Spring's templates supply callbacks that alleviate try/catch blocks - but give you full power of the API.
JmsTemplate has a couple of capabilities: it handles acquisition and release of resources and translates checked JMS Exceptions to a parallel hierarchy of RuntimeExceptions. It's also capable of converting a payload to the corresponding JMS message type with a MessageConverter strategy. Lastly, it provides convenience methods to allow sending asynchronous messages.
Now Mark is showing us how you configure a ConnectionFactory, Queue and JmsTemplate in a Spring context file. The first couple of beans only take 3 lines of code to configure, the 3rd one takes 4 because it has a dependency on the first two. Pretty easy configuration if you ask me. After composing bean definitions, Mark created a JUnit test and called
jmsTemplate.convertAndSend() to send a message in 2 lines of Java code.
To receive messages with JmsTemplate (pre Spring 2.0), you could use synchronous receive calls:
receive(String). There are also
In Spring 2.0, they added the ability to do MessageListener containers to enable asynchronous reception in a non application server environment. Implementations include SimpleMessageListenerContainer, DefaultMessageListenerContainer and ServerSessionMessageListenerContainer. The DMLC adds transactional behavior, and the SSMLC hooks into the server's SPI. Spring's MessageListenerAdapter enables the delegation to a POJO for handling the payload.
For the next 1/2 hour or so, Mark wrote a bunch of Java and XML to create a simple Trader application. About the same time, I got managed to get an internet connection from somewhere and started browsing the net and answering e-mail. Every once in a while I looked up to see Mark's code - it all looks very simple and straight forward. In Spring 2.1, a <jms:*> namespace will be added to simplify the XML configuration.
For those of you out there using Spring's JMS support - are there any issues you've run into? Are you using it in production? It's always pimped as "awesome", so I'm looking for pain points that folks might encounter when using it.
Related: Spring's JMS Documentation and ActiveMQ's JmsTemplate Gotchas.