We already discussed the fundamental concepts of JMS . We already discussed few techniques to ensure reliability in messaging :The message persistence in JMS and message priority in JMS .In this chapter we are discussing another way which is using to ensure reliable message delivery:message expiry in JMS.
Message Expiry in JMS
By default a message never expires.In some cases message will become obsolete after a particular time period. In such situation it is desirable to set expiration time . After the message expires, it will not be delivered.
We can set the expiration time in program in two ways.
a)Using setTimeToLive() method of MessageProducer interface to set the expiry time of messages from that producer.
Example:setTimeToLive(10000)
The above statement sets the expiry time 10000 milliseconds(10 seconds)
b)Using the overridden method publish()
Example :topPublisher.publish(message, DeliveryMode.PERSISTENT, 3,
10000)
The fourth argument gives the expiry time as 10000 milliseconds .
Message Expiry in JMS example
We are using openJMS as JMS provider . Before running the clients, the OpenJMS should be configured and started .And the necessary libraries should be placed in the project space.Those things were explained in a previous article.
FirstClient.java
import java.util.Properties;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class FirstClient {
Context context = null;
ConnectionFactory factory = null;
Connection connection = null;
Destination destination = null;
Session session = null;
MessageProducer producer = null;
public FirstClient() {
}
public void sendMessage() {
Properties initialProperties = new Properties();
initialProperties.put(InitialContext.INITIAL_CONTEXT_FACTORY,
"org.exolab.jms.jndi.InitialContextFactory");
initialProperties.put(InitialContext.PROVIDER_URL,
"tcp://localhost:3035");
try {
context = new InitialContext(initialProperties);
factory = (ConnectionFactory) context.lookup("ConnectionFactory");
destination = (Destination) context.lookup("queue1");
connection = factory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
producer = session.createProducer(destination);
connection.start();
TextMessage message = session.createTextMessage();
message.setText("Hello...This is a message");
producer.setTimeToLive(10 * 1000);
producer.send(message);
System.out.println("Sent message: " + message.getText());
} catch (JMSException ex) {
ex.printStackTrace();
} catch (NamingException ex) {
ex.printStackTrace();
}
if (context != null) {
try {
context.close();
} catch (NamingException ex) {
ex.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (JMSException ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args) {
FirstClient firstClient = new FirstClient();
firstClient.sendMessage();
}
}
SecondClient.java
import java.util.Properties;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class SecondClient {
Context context = null;
ConnectionFactory factory = null;
Connection connection = null;
Destination destination = null;
Session session = null;
MessageConsumer consumer = null;
public SecondClient() {
}
public void receiveMessage() {
Properties initialProperties = new Properties();
initialProperties.put(InitialContext.INITIAL_CONTEXT_FACTORY,
"org.exolab.jms.jndi.InitialContextFactory");
initialProperties.put(InitialContext.PROVIDER_URL,
"tcp://localhost:3035");
try {
context = new InitialContext(initialProperties);
factory = (ConnectionFactory) context.lookup("ConnectionFactory");
destination = (Destination) context.lookup("queue1");
connection = factory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
consumer = session.createConsumer(destination);
connection.start();
Message firstMessage = consumer.receive();
if (firstMessage instanceof TextMessage) {
TextMessage text = (TextMessage) firstMessage;
System.out.println("Message Received is : "
+ text.getText());
}
} catch (JMSException ex) {
ex.printStackTrace();
} catch (NamingException ex) {
ex.printStackTrace();
}
if (context != null) {
try {
context.close();
} catch (NamingException ex) {
ex.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (JMSException ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args) {
SecondClient secondClient = new SecondClient();
secondClient.receiveMessage();
}
}
The first client sends a simple text message . Expiration time also set as 10 seconds.Second client simply receives the message from destination and displays it.
Output
Before running the clients the openJMS should be started and all the libraries should be there in project space as discussed earlier.
If we run both the clients within 10 seconds interval ,second client will receive the message sent by first client. Otherwise second client will not receive the message.