Software applications that use Java Messaging Service(JMS) are required to ensure the reliable delivery of message between clients. Message persistency in JMS API provides a way to ensure this.

JMS API provides two delivery modes for message delivery:
1. Persistent delivery mode
2. Non-Persistent delivery mode.

Please go through JMS Concepts – Persistent and Durable to read more on message delivery modes. In my other JMS tutorials you will find all message delivery modes are Persistent because if you do not specify any mode for message delivery then by default the message delivery mode is Persistent.

Please go through the tutorial Apache ActiveMQ Configuration in Windows before proceeding below.

Prerequisites

The following configurations are required in order to run the application

Eclipse Kepler
JDK 1.8
Have maven 3 installed and configured
Apache ActiveMQ dependency in pom.xml

Step 1. Create a standalone maven based web project in Eclipse

Step 2. Modify the pom.xml file as shown below.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.roytuts</groupId>
	<artifactId>jms</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>jms</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
		<activemq.version>5.11.1</activemq.version>
	</properties>

	<dependencies>
		<!-- activemq -->
		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-all</artifactId>
			<version>${activemq.version}</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>${java.version}</source>
					<target>${java.version}</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Step 3. Create below jndi.properties file under src/main/resources

java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url=tcp://localhost:61616
queue.queue/queueName=IN_QUEUE

Step 4. Create below producer class which sends message to a queue IN_QUEUE

package com.roytuts.jms.queue;

import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class Producer {

	public void produceMessage() {
		InitialContext initialContext = null;
		QueueConnectionFactory connectionFactory;
		QueueConnection connection = null;
		QueueSender sender;
		QueueSession session;
		Queue queue;
		try {
			// Step 1. Create an initial context to perform the JNDI lookup.
			initialContext = new InitialContext();
			// Step 2. Look-up the JMS queue
			queue = (Queue) initialContext.lookup("queue/queueName");
			// Step 3. Look-up the JMS queue connection factory
			connectionFactory = (QueueConnectionFactory) initialContext.lookup("ConnectionFactory");
			// Step 4. Create a JMS queue connection
			connection = connectionFactory.createQueueConnection();
			// Step 5. Set the client-id on the connection
			connection.start();
			// step 6. Create queue session
			session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
			// step 7. Create queue sender
			sender = session.createSender(queue);
			// step 8. non-persistence delivery of message
			sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
			// Step 9. Create a text message
			TextMessage message = session.createTextMessage("This sample message is consumed by consumer");
			// Step 10. Send the text message to the queue
			sender.send(message);
		} catch (JMSException | NamingException ex) {
			ex.printStackTrace();
		} finally {
			if (connection != null) {
				try {
					connection.close();
				} catch (JMSException e) {
					e.printStackTrace();
				}
			}
			if (initialContext != null) {
				try {
					initialContext.close();
				} catch (NamingException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

Step 5. Create below consumer

package com.roytuts.jms.queue;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class Consumer {

	public void consumeMessage() {
		InitialContext initialContext = null;
		QueueConnectionFactory connectionFactory;
		QueueConnection connection = null;
		MessageConsumer consumer;
		QueueSession session;
		Queue queue;
		try {
			// Step 1. Create an initial context to perform the JNDI lookup.
			initialContext = new InitialContext();
			// Step 2. Look-up the JMS queue
			queue = (Queue) initialContext.lookup("queue/queueName");
			// Step 3. Look-up the JMS queue connection factory
			connectionFactory = (QueueConnectionFactory) initialContext.lookup("ConnectionFactory");
			// Step 4. Create a JMS queue connection
			connection = connectionFactory.createQueueConnection();
			// Step 5. Set the client-id on the connection
			connection.start();
			// step 6. Create queue session
			session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
			// step 7. Create queue sender
			consumer = session.createConsumer(queue);
			// Step 8. receive text message
			Message message = consumer.receive();
			if (message != null && message instanceof TextMessage) {
				TextMessage textMessage = (TextMessage) message;
				System.out.println("Consumer received a message produced by Producer : " + textMessage.getText());
			} else if (message == null) {
				System.out.println("Consumer fails to receive the message sent by the producer.");
			} else {
				throw new JMSException("Message must be a type of TextMessage");
			}
		} catch (JMSException | NamingException ex) {
			ex.printStackTrace();
		} finally {
			if (connection != null) {
				try {
					connection.close();
				} catch (JMSException e) {
					e.printStackTrace();
				}
			}
			if (initialContext != null) {
				try {
					initialContext.close();
				} catch (NamingException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

Step 5. Create below classes for testing

package com.roytuts.jms.queue.test;

import com.roytuts.jms.queue.Producer;

public class ProducerTest {

	public static void main(String[] args) {
		new Producer().produceMessage();
	}

}
package com.roytuts.jms.queue.test;

import com.roytuts.jms.queue.Consumer;

public class ConsumerTest {

	public static void main(String[] args) {
		new Consumer().consumeMessage();
	}

}

Step 6. While your ActiveMQ broker running, first run the class ProducerTest then ConsumerTest. You will see the below output in console

Consumer received a message produced by Producer : This sample message is consumed by consumer

Now to test on broker restart, do the following.

First run the ProducerTest class. Stop the broker. Again start the broker. Now run the ConsumerTest class. The consumer will not receive any output in the console because for Non-Persistent delivery message is not saved in the disk or memory for later use.

But if you comment the line sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT); and you will see the output will be same on broker restart. Because by default the message delivery mode is Persistent. If you want you can also use sender.setDeliveryMode(DeliveryMode.PERSISTENT); for Persistent message delivery.

Thanks for reading.

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials Twitter Facebook  Google Plus Linkedin Or Email Me

Leave a Reply

Your email address will not be published. Required fields are marked *