JMS application with embedded messaging engine in Open Liberty

Last Updated:  June 16, 2022 | Published: August 19, 2018

For messaging, I have always thought of Apache Kafka as the central solution for messaging. While learning more about Java EE I came along the Java Message Service (JMS) specification and gave it a try. In addition, I wanted to learn more about the JMS capabilities of the Open Liberty application server.

In this blog post, I'll show you how to create a simple messaging application with JMS, JPA and JSON-B which will be deployed to Open Liberty 18.0.0.2 within a Docker container. For simplification, I'll use JMS to communicate within one .war  using a JMS queue. The application will periodically publish a simple entity as JSON and the message will be received by a Message Driven Bean and stored to the database.

JMS configuration for Open Liberty

With JMS you can choose between queues for point-to-point communication or topics for publish-subscribe use cases. The Open Liberty server has the built-in feature wasJmsServer-1.0 which gets activated while using the Java EE 8 full profile feature javaee-8.0. With this feature enabled you can configure the embedded messaging engine like the following:

As Open Liberty doesn't provide an embedded relational database out of the box, I have to configure it in the server.xml file. Therefore I have to add the embedded database (Apache Derby.jar file to the application server and define a data source like the following:

Sending and receiving JMS messages

The central message for the JMS communication and for JPA looks like the following:

To publish a new message every two seconds, I'll use a simple EJB to schedule this task. In addition, I'll check the number of messages in the database every ten seconds:

The JmsMessgeSender class is an EJB that connects to the embedded JmsFactory and creates a MessageProducer for the JMS queue. As the JMS classes Connection, Session and MessageProducer all extend the AutoClosable interface, I'll use Java's try-with-resources statement to automatically close the opened connections:

For message serialization, I use JSON-B to create a JSON representation of the object.

To receive the message within the JMS queue, I'll use a Message Driven Bean where I just have to implement the onMessage(Message message) method:

This bean will cast the incoming generic Message to a TextMessage and use JSON-B again to parse the JSON.

For developing Message Driven Beans, Open Liberty provides a feature called mdb-3.2 which is activated with the javaee-8.0 feature. To receive the incoming message within the Message Driven Bean you need this feature and you have to configure a so-called jmsActivationSpec within the server.xml:

The id attribute has the following structure: {nameOfTheWar}/{classNameOfTheMessageDrivenBean}. The destinationRef has to point to the already configured JmsQueue within the server.xml.

Running the application should result in the following log:

For a simple deployment on your machine, I created a Dockerfile which will copy the required .jar file and the server configuration to the Open Liberty server.

You can find the whole codebase as always on GitHub.

Happy messaging,

Phil.

>