Java Message Service: Dr. Stephan Fischli
Java Message Service: Dr. Stephan Fischli
Java Message Service: Dr. Stephan Fischli
Summer 2005
2
Goals
Contents
● Introduction
● Programming Model
● Messages
● Basic Messaging
● Advanced Messaging
4
Introduction
Messaging Systems
Application Application
Messaging
System
Application Application
6
Messaging versus RMI
1: send 3: deliver
Producer Destination Consumer
2: return 4: return
Client Client
Message
Server
Client Client
8
Java Message Service
Application
Messaging Domains
Subscriber
Publisher Topic
Subscriber
10
Messaging Domains (cont.)
Receiver
Sender Queue
Receiver
11
Guaranteed Delivery
Message
Producer Consumer
Server
Persistent
Store
12
Application Scenarios
13
References
14
15
16
Programming Model
17
Overview
*
JNDI Connection
Context Factory
*
Connection
* *
Destination Message Destination
19
Connection Factories
ConnectionFactory factory =
(ConnectionFactory)context.lookup("ConnectionFactory");
20
Destinations
Destination destination =
(Destination)context.lookup("Topic");
21
Connections
22
Sessions
Session session =
connection.createSession(false, Session.AUTO_ACKNOWLEDGE );
23
Message Producers
24
Message Consumers
25
Message Listener
26
27
28
Messages
29
Headers
Properties
Body
30
Headers
31
JMSDestination
● The JMSDestination header identifies the destination of a message
with either a topic or a queue
JMSDeliveryMode
● A persistent message should be delivered once-and-only-once even if
the JMS provider fails
● A non-persistent message is delivered at-most-once, which means
that it can be lost if the JMS provider fails
● The delivery mode can be set on the message producer using the
setJMSDeliveryMode() method (default is persistent)
JMSMessageID
● The JMSMessageID is a string value that uniquely identifies a
message
32
Automatically Assigned Headers (cont.)
JMSTimestamp
● The JMSTimestamp header is set automatically by the message
producer when the message is sent
JMSExpiration
● A message's expiration date prevents the message from being
delivered to consumers after it has expired
● The expiration time can be set on the message producer using the
setTimeToLive() method (by default a message doesn't expire)
JMSRedelivered
● The JMSRedelivered header indicates that a message was redelivered
to the consumer
● A message may be marked redelivered if a consumer failed to
acknowledge previous delivery of the message
33
JMSPriority
● The message server may use a message's priority to prioritize
delivery to consumers
● Levels 0 – 4 are gradations of normal priority, levels 5 – 9 are
gradations of expedited priority
● The priority can be set on the message producer using the
setPriority() method (default is 4)
34
Developer-Assigned Headers
JMSReplyTo
● The JMSReplyTo header contains a destination to which the
consumer of the message should reply to
JMSCorrelationID
● The JMSCorrelationID header is used for associating the current
message with some previous message, e.g. to tag a message as a reply
to a previous message
JMSType
● The JMSType header can be set by the message producer to identify
the message structure and type of payload
35
Properties
36
Message Types
Message TextMessage
ObjectMessage
BytesMessage
StreamMessage
MapMessage
● The message types represent the kind of payload a message can have
● Some types were included to support legacy payloads, other types
were defined to facilitate emerging needs
37
Message
● The type Message serves as the base interface of the other message
types
● It contains only JMS headers and properties and is used for event
notification
TextMessage
● The type TextMessage carries a String as its payload
● It is useful for exchanging simple text messages and more complex
character data like XML documents
ObjectMessage
● The type ObjectMessage carries a serializable Java object as its
payload
● The producer and consumer must be Java programs, and the class
definition of the object has to be available to both of them
38
Message Types (cont.)
BytesMessage
● The ByteMessage type carries an array of bytes as its payload
● It is useful for exchanging data in an application's native format or
when the message payload is opaque to the JMS client
StreamMessage
● The StreamMessage type carries a stream of primitive Java types as
its payload
● It keeps track of the order and types of primitives written to the
message
MapMessage
● The MapMessage type carries a set of name-value pairs as its payload
● It is useful for delivering keyed data that may change from one
message to the next
39
40
Basic Messaging
41
Publish-and-Subscribe
subscribe
Subscriber
publish deliver
Publisher
Topic
subscribe
Subscriber
deliver
send receive
Sender Queue Receiver
acknowledge
43
Example: SimpleProducer
import java.io.*;
import javax.jms.*;
import javax.naming.*;
44
Example: SimpleProducer (cont.)
// send messages
BufferedReader in =
new BufferedReader(new InputStreamReader(System.in));
while (true) {
String text = in.readLine();
if (text.equals("")) break;
TextMessage message = session.createTextMessage();
message.setStringProperty("user", args[1]);
message.setText(text);
producer.send(message);
}
connection.close();
System.exit(0);
}
}
45
Example: SimpleConsumer
import javax.jms.*;
import javax.naming.*;
46
Example: SimpleConsumer (cont.)
// receive messages
connection.start();
while (true) {
TextMessage message = (TextMessage)consumer.receive(10000);
if (message == null) break;
String user = message.getStringProperty("user");
String text = message.getText();
System.out.println(user + ": " + text);
}
connection.close();
System.exit(0);
}
}
47
Example: AsynchronousConsumer
import javax.jms.*;
import javax.naming.*;
// register listener
consumer.setMessageListener(new TextListener());
48
Example: AsynchronousConsumer (cont.)
// receive messages
connection.start();
System.in.read();
connection.close();
System.exit(0);
}
}
49
Durable Subscriptions
Subscription
create unsubscribe
Connection Connection
start close start close
import javax.jms.*;
import javax.naming.*;
51
// register listener
consumer.setMessageListener(new TextListener());
// receive messages
connection.start();
System.in.read();
if (args.length == 3 && args[2].equals("unsubscribe")) {
consumer.close();
session.unsubscribe(args[1]);
}
connection.close();
System.exit(0);
}
}
52
Browsing a Queue
53
Example: SimpleBrowser
import java.util.*;
import javax.jms.*;
import javax.naming.*;
54
Example: SimpleBrowser (cont.)
// browse messages
connection.start();
Enumeration enum = browser.getEnumeration();
while (enum.hasMoreElements()) {
TextMessage message = (TextMessage)enum.nextElement();
String user = message.getStringProperty("user");
String text = message.getText();
System.out.println(user + ": " + text);
}
connection.close();
System.exit(0);
}
}
55
56
Advanced Messaging
57
Message Selectors
58
Example: SelectiveConsumer
import javax.jms.*;
import javax.naming.*;
59
// receive messages
connection.start();
while (true) {
TextMessage message = (TextMessage)consumer.receive(10000);
if (message == null) break;
String user = message.getStringProperty("user");
String text = message.getText();
System.out.println(user + ": " + text);
}
connection.close();
System.exit(0);
}
}
60
Temporary Destinations
61
Example: SimpleRequestor
import java.io.*;
import javax.jms.*;
import javax.naming.*;
62
Example: SimpleRequestor (cont.)
// send request
BufferedReader in =
new BufferedReader(new InputStreamReader(System.in));
String text = in.readLine();
TextMessage request = session.createTextMessage();
Destination temp = session.createTemporaryQueue();
request.setJMSReplyTo(temp);
request.setText(text);
producer.send(request);
// receive reply
connection.start();
MessageConsumer consumer = session.createConsumer(temp);
TextMessage reply = (TextMessage)consumer.receive();
System.out.println(reply.getText());
connection.close();
System.exit(0);
}
}
63
Example: SimpleReplier
import javax.jms.*;
import javax.naming.*;
64
Example: SimpleReplier (cont.)
while (true) {
// receive request
TextMessage request = (TextMessage)consumer.receive(10000);
if (request == null) break;
String id = request.getJMSMessageID();
String text = request.getText();
System.out.println(id + ": " + text);
// send reply
Destination temp = request.getJMSReplyTo();
TextMessage reply = session.createTextMessage();
reply.setJMSCorrelationID(id);
reply.setText(text);
MessageProducer producer = session.createProducer(temp);
producer.send(reply);
}
connection.close();
System.exit(0);
}
}
65
Message Acknowledgment
1: send 4: deliver
Message
Producer Consumer
Server
3: ack 5: ack
2: persist 6: delete
Persistent
Store
66
Failure and Message Redelivery
67
Acknowledgment Modes
68
Example: AcknowledgeConsumer
import javax.jms.*;
import javax.naming.*;
69
// receive messages
connection.start();
while (true) {
TextMessage message = (TextMessage)consumer.receive(10000);
if (message == null) break;
String text = message.getText();
if (message.getJMSRedelivered())
System.out.print("Redelivered: ");
System.out.println(text);
if (args.length == 2 && args[1].equals("acknowledge"))
message.acknowledge();
}
connection.close();
System.exit(0);
}
}
70
Transacted Messages
1: send 4: deliver
2: send Message 5: deliver
Producer Consumer
Server
3: commit/ 6: commit/
rollback rollback
71
Example: TransactedProducer
import java.io.*;
import javax.jms.*;
import javax.naming.*;
72
Example: TransactedProducer (cont.)
// send messages
BufferedReader in =
new BufferedReader(new InputStreamReader(System.in));
while (true) {
String text = in.readLine();
if (text.equals("")) break;
TextMessage message = session.createTextMessage();
message.setStringProperty("user", args[1]);
message.setText(text);
producer.send(message);
}
// commit or rollback
if (args.length == 3 && args[2].equals("commit"))
session.commit();
else session.rollback();
connection.close();
System.exit(0);
}
}
73
Distributed Transactions
1: begin 5: commit
Transaction
Manager
74
75
76