This document provides an overview of JMS and message-driven POJOs. It discusses JMS message types, the JMS API, configuration, sending and receiving messages, request/reply messaging, using Spring's JMS support, and implementing message-driven POJOs with Spring. Code examples are provided to demonstrate sending and receiving messages, request/reply messaging, and implementing message-driven POJOs that receive messages. The presentation includes an agenda, introductions to messaging concepts and models, descriptions of each message type, and discussions of Spring's JMS support and the three options for implementing message-driven POJOs with Spring.
Introduction to JMSand
Message-Driven POJOs
Matt Stine
Memphis JUG
March 19, 2009
2.
Agenda
Introduction to Messaging
JMSMessage Types
The JMS API
JMS Conļ¬guration
Sending and Receiving Mesages
Request/Reply Messaging
Using Springās JMS Support
Message-Driven POJOs with Spring
Messaging Models
Point to Point
Sender Sender Sender
Queue Queue
Receiver Receiver Receiver
8.
Messaging Models
Point to Point Publish and Subscribe
Sender Sender Sender Subscriber Subscriber
Queue Queue Topic
Receiver Receiver Receiver Publisher
TextMessage
Used for sendingsimple String text or XML
Sender
TextMessage message = session.createTextMessage();
StringBuffer text = new StringBuffer();
text.append("<priceRequest>");
text.append(" <symbol>AAPL</symbol>");
text.append("</priceRequest>");
message.setText(messageText.toString());
sender.send(message);
Receiver
TextMessage msg = (TextMessage)message;
String xml = msg.getText();
MapMessage
Used for sendingtype-safe name-value pairs
Sender
MapMessage message = session.createMapMessage();
message.setString("side", "BUY");
message.setString("symbol", "AAPL");
message.setLong("shares", 100);
sender.send(message);
Receiver
MapMessage msg = (MapMessage)message;
String side = msg.getString("side");
String symbol = msg.getString("symbol");
long shares = msg.getLong("shares");
14.
BytesMessage
Used for sendinga formatted series of primitive native-format bytes
Sender
BytesMessage message = session.createBytesMessage();
message.writeUTF("BUY");
message.writeUTF("AAPL");
message.writeInt(100);
sender.send(message);
Receiver
BytesMessage msg = (BytesMessage)message;
String side = msg.readUTF();
String symbol = msg.readUTF();
int shares = msg.readInt();
15.
StreamMessage
Used for sendinga formatted series of bytes as Java primitive types
Sender
StreamMessage message = session.createStreamMessage();
message.writeString("BUY");
message.writeString("AAPL");
message.writeInt(100);
sender.send(message);
Receiver
StreamMessage msg = (StreamMessage)message;
String side = msg.readString();
String symbol = msg.readString();
long shares = msg.readLong();
Conļ¬guring a JMSProvider
Open Source Project
(http://openjms.sourceforge.net)
Comes preconļ¬gured with Derby, but can be used
with any JDBC 2.0 compliant database
Includes an embedded JNDI Provider (Spice)
Conļ¬gured using the openjms.xml conļ¬guration ļ¬le
Sending and Receiving
Messages
Connectto the JMS provider (OpenJMS) and obtain
a connection to the message server
Send a JMS TextMessage with XML containing a
stock trade order
Create an asynchronous message listener to receive
the XML stock trade order
Request/Reply Messaging
Modify thesender to block and wait for a return
message
Modify the asynchronous message listener to send a
conļ¬rmation number for the trade
Spring JMS Support
Simpliļ¬esuse of JMS API
Infrastructure in XML conļ¬guration
JmsTemplate in code
Message production
33.
Spring JMS Support
Simpliļ¬esuse of JMS API
Infrastructure in XML conļ¬guration
JmsTemplate in code
Message production
Synchronous nessage reception
34.
Spring JMS Support
Simpliļ¬esuse of JMS API
Infrastructure in XML conļ¬guration
JmsTemplate in code
Message production
Synchronous nessage reception
Letās Code!!!
Message-Driven POJOs
with Spring
Enablesasynchronous communication
Little or no coupling to JMS
Three options:
Implement javax.jms.MessageListener
Implement Springās SessionAwareMessageListener
42.
Message-Driven POJOs
with Spring
Enablesasynchronous communication
Little or no coupling to JMS
Three options:
Implement javax.jms.MessageListener
Implement Springās SessionAwareMessageListener
Conļ¬gure via Springās MessageListenerAdapter
43.
Message-Driven POJOs
with Spring
Enablesasynchronous communication
Little or no coupling to JMS
Three options:
Implement javax.jms.MessageListener
Implement Springās SessionAwareMessageListener
Conļ¬gure via Springās MessageListenerAdapter
Add to Spring-provided MessageListenerContainer
MDP Live Coding
Conļ¬gure
MessageListenerContainer
ImplementMDP that receives a
JMS message object using
default handler method
Implement MDP with automatic
message conversion
Implement MDP with automatic
message conversion and Letās Code!!!
custom handler method
50.
Credits
http://www.everystockphoto.com/photo.php?imageId=2743792
http://www.everystockphoto.com/photo.php?imageId=1218094
http://www.everystockphoto.com/photo.php?imageId=4463765
http://www.everystockphoto.com/photo.php?imageId=2106868
http://www.everystockphoto.com/photo.php?imageId=1310486
http://www.everystockphoto.com/photo.php?imageId=708018
http://www.everystockphoto.com/photo.php?imageId=3012910
Richards, Mark. Introduction to JMS Messaging. NFJS Gateway Software Symposium 2009
Richards, Mark. āMessage Driven POJOs: Messaging Made Easy.ā No Fluff Just Stuff, the
Magazine. Jan-Mar 2009.
http://www.allapplabs.com/interview_questions/jms_interview_questions.htm#q11
Editor's Notes
#4Ā So before we get into the details of JMS, let&#x2019;s take a bird&#x2019;s eye view of the landscape. What is messaging all about, and why would we want to use it? Any ideas?
#5Ā So here&#x2019;s the most basic look at a messaging architecture. You have a component that sends messages, which are sent to some type of message channel. This message channel is charged with routing the messages to other components that receive and process messages. So you have multiple components, maybe even multiple systems. They are decoupled - the sender does not know the details of the receiver, nor does the receiver know the details of the sender. What are some use cases for an architecture like this?
Asynchronous processing, remoting, SOA, interoperability, integration....how about increasing user productivity? Tell the story about the guy who sends off a request and the goes to get his coffee, gets distracted, finally comes back vs. the guy who can send off a request, knows he&#x2019;ll get a notification when it&#x2019;s done, and continues working.
#6Ā So we&#x2019;ll start off with point-to-point (or p2p) models. This first examples is what we&#x2019;ll call Fire and Forget. You send to a queue and move on with your day. A receiver picks up the message from the queue, processes it, and moves on with its day. With p2p you have on and only one receiver per message. You may have multiple receivers load balanced, but only one component can receive each message. The second model is what we&#x2019;ll call request/reply or &#x201C;Pseudosynchronous.&#x201D; Here the sender blocks and waits for a response from the receiver. Finally we have the publish and subscribe or pub/sub model. Here you publish or &#x201C;broadcast&#x201D; to not a queue, but a topic. Multiple subscribers can &#x201C;listen&#x201D; to this topic, and all will get a copy of each message.
#7Ā So we&#x2019;ll start off with point-to-point (or p2p) models. This first examples is what we&#x2019;ll call Fire and Forget. You send to a queue and move on with your day. A receiver picks up the message from the queue, processes it, and moves on with its day. With p2p you have on and only one receiver per message. You may have multiple receivers load balanced, but only one component can receive each message. The second model is what we&#x2019;ll call request/reply or &#x201C;Pseudosynchronous.&#x201D; Here the sender blocks and waits for a response from the receiver. Finally we have the publish and subscribe or pub/sub model. Here you publish or &#x201C;broadcast&#x201D; to not a queue, but a topic. Multiple subscribers can &#x201C;listen&#x201D; to this topic, and all will get a copy of each message.
#8Ā So we&#x2019;ll start off with point-to-point (or p2p) models. This first examples is what we&#x2019;ll call Fire and Forget. You send to a queue and move on with your day. A receiver picks up the message from the queue, processes it, and moves on with its day. With p2p you have on and only one receiver per message. You may have multiple receivers load balanced, but only one component can receive each message. The second model is what we&#x2019;ll call request/reply or &#x201C;Pseudosynchronous.&#x201D; Here the sender blocks and waits for a response from the receiver. Finally we have the publish and subscribe or pub/sub model. Here you publish or &#x201C;broadcast&#x201D; to not a queue, but a topic. Multiple subscribers can &#x201C;listen&#x201D; to this topic, and all will get a copy of each message.
#9Ā So basically you have two parts, the header and the payload. JMS distinguishes within the header between what it calls the &#x201C;Header&#x201D; which includes all of the standard JMS properties, and the &#x201C;Properties&#x201D; which includes application and/or provider-specific extension properties, as well as JMS extensions (otherwise known as JMSX properties), which may or may not be supported by all JMS providers. Finally you have the payload or &#x201C;Message Body,&#x201D; which distinguished what type of JMS message we&#x2019;re talking about and the possible payloads it may carry.
#10Ā So just as we have many different colors of mailboxes here, there are many different types or &#x201C;colors&#x201D; of JMS messages out there.
#12Ā This is super cool, huh? Well, what&#x2019;s wrong with this? One of the goals of messaging is decoupling of the sender and receiver. Well, in this case both Sender and Receiver must be aware of TradeData. So we end up with a tightly coupled architecture, we have versioning issues (i.e. if TradeData changes, we have to update multiple systems), and it forces heterogeneity of systems (i.e. I can&#x2019;t have a non-Java consumer). UC - same machine, interservice communication.
#14Ā This can be useful for transfer of data between two applications in their native format which may not be compatible with other Message types. It&#x2019;s also useful where JMS is used purely as a transport between two systems and the message payload is opaque to the JMS client. There is no type information encoded into the message - for example, it is possible for the sender to encode a long and the sender to read a short, resulting in semantically incorrect interpretation - it is purely up to the receiver to properly interpret the message.
#15Ā The alternative is the StreamMessage. This type maintains a boundary between the different data types stored, storing the data type information along with the value of the primitive. StreamMessages strictly prohibit reading incorrect types from the data stream.
#16Ā In fact, here are the type conversions that are supported by the StreamMessage. As you can see, just like in regular Java code, you can read to a bigger type but not to a smaller type (with the exception of String, which can be read to any of the supported types).
#17Ā So a couple of weekends ago I attended the NFJS symposium in St. Louis. While watching the presentations there, I gained a renewed appreciation for what properly placed images can do to enhance a talk. In fact, the use of Creative Commons licensed images came up several times. For this talk, all of the images are actually Creative Commons licensed, meaning in this case that all I have to do to use them legally is run the credits at the end of the talk. So, while searching for images for this slide, I actually entered &#x201C;API&#x201D; as my search criteria, thinking that nothing would come up. Imagine my surprise when I got this really cool photo of a sign. So, with that let&#x2019;s examine the API...
#18Ā So staring with JMS 1.1, the spec consolidated the various interfaces such that all interfaces descend from common generic types, shown here.
#19Ā As you can see, there&#x2019;s a one-to-one relationship between all of the interfaces here and the generic ones, with Message carrying over.
#21Ā So this is probably how many of us feel when it comes to configuration. Thankfully, configuring JMS can be relatively simple depending on your provider.
#22Ā For this talk we&#x2019;ll be working with OpenJMS, which is great for development and testing, but is not production ready. In fact, it has been in beta for years!
Go to TextMate and look at the openjms.xml file!