JMS Queue Server and Client Example Based On an ActiveMQ Provider
The basics of messaging services for Java apps, along with a client example based on ActiveMQ.
Join the DZone community and get the full member experience.
Join For FreeWhat is JMS?
Java Message Service could be considered as high level framework that communicates two or more clients each other by sending messages. JMS is fully supported by Java EE and has been described in JSR -914 (see links section).
Here are the base operations that we can do:
Send messages
Receive messages
Typically, one client creates a message and sends it to the JMS server, and another client receives it and performs some kind of operation. Of course, this is a high level overview, and low level processes are more complicated.
Where Do We Use It?
Well we could use JMS everywhere where we need to increase scalability, integrate different environments, include batch processing support, or asynchronous communication without time pressure.
A common use is to send email, the client creates an email message from the template, and sends it to the MQ server. The receiver then receives the message from MQ server and sends the email.
But as you can see there are many other processes that could be implemented that way.
Sample MQ Providers List?
Amazon SQS
ActiveMQ
Oracle Weblogic
HornetQ (previously JBoss messaging) see link number 2.
What is ActiveMQ?
ActiveMQ is an implementation of Message Oriented Middleware which is used to communicate via JMS clients. As we can read at the official page (see link number 3), it is an open source system that is fast, supports cross language clients and protocols, and, most importantly, fully supports JMS 1.1 specifications.
The latest version is 5.13.0, and this version will be used in the demo.
ActiveMQ Server
From the download section of the official ActiveMQ page (see link number 3), you can download the latest server binary package. After un-zipping, it took almost 100MB of disk space. Unzipped binaries are all you need to start your server.
My Windows machine starting script is located at: apache-activemq-5.13.0\bin. I use activemq.bat but there are similar scripts for Linux too.
Bat script setup local env and finally run the jar file called activemq.jar, which is located at bin folder.
After running in the command line, starting the script, and successfully starting the server you should see something similar to this:
Now you could type http://localhost:8161/admin/ to access Your ActiveMQ server administration console, note that the default login and password is admin.
It should look like this:
Now you could add your first queue in the Queues menu.
ActiveMQ Client Example
I created a sample client for an ActiveMQ server in Java 8 using threads and lambdas. You can find all the code at my GitHub: https://github.com/tjancz/jms-activemq-example.git
Below you can see the sender code:
package it.janczewski.examples.utils;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jms.*;
import java.math.BigInteger;
import java.security.SecureRandom;
public class Sender {
private final Logger logger = LoggerFactory.getLogger(Sender.class);
private SecureRandom random = new SecureRandom();
public void createTask(){
String taskName = generateTaskName();
Runnable sendTask = () -> {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = null;
try {
connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("TJ Test");
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
String text = "Hello from: " + taskName + " : " + this.hashCode();
TextMessage message = session.createTextMessage(text);
logger.info("Sent message hash code: "+ message.hashCode() + " : " + taskName);
producer.send(message);
session.close();
connection.close();
} catch (JMSException e) {
logger.error("Sender createTask method error", e);
}
};
new Thread(sendTask).start();
}
private String generateTaskName() {
return new BigInteger(20, random).toString(16);
}
}
And the receiver code:
package it.janczewski.examples.utils;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jms.*;
public class Reciver implements ExceptionListener{
private final Logger logger = LoggerFactory.getLogger(Reciver.class);
public void createRecieveTask() {
Runnable recTask = () -> {
try {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = connectionFactory.createConnection();
connection.start();
connection.setExceptionListener(this);
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("TJ Test");
MessageConsumer consumer = session.createConsumer(destination);
Message message = consumer.receive(4000);
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
String text = textMessage.getText();
logger.info("Received TextMessage object: " + text);
} else {
logger.info("Received other object type with message: " + message);
}
consumer.close();
session.close();
connection.close();
} catch (JMSException e) {
logger.error("Reciver createRecieveTask method error", e);
}
};
new Thread(recTask).start();
}
@Override
public void onException(JMSException exception) {
logger.error("Recieve error occured.");
}
}
If you would like to see all working stuff, just clone it from my GitHub repo.
There is also great documentation on the ActiveMQ page.
Summary
JMS is not scary as it looks and, ActiveMQ is a great MOM that could easily help you set up message queues and integrate different systems.
Links
Opinions expressed by DZone contributors are their own.
Comments