I’m currently integrating JMS (Java Messaging Service) into a project. Being a true enterprise component it has a very complex nomenclature and consists itself of many modules to cover all kinds of topologies. To aid other newcomers here is an overview of what I’ve learned so far.

Introduction

The Java Messaging Service is an official part of Java EE and defined in JSR 914. In its own words it provides “loosely coupled, reliable, and asynchronous” messaging services for Java applications. Essentially this means that the service is fault-tolerant towards network and application failures and messages will reach their intended target eventually. However, in contrast to other means such as RPC it is not designed for time-critical communication.

Components

The major building blocks of JMS are brokers, transports, queues / topics, producers and consumers.

Consumers and producers

Producers and consumers, commonly referred to as clients, are producing and consuming messages respectively, just like the Consumer-Producer pattern. They are the main point where your application interacts with the JMS infrastructure by sending and receiving messages.

Brokers

Brokers are responsible for storing and forwarding messages to their intended targets, that’s why one common JMS topology is referred to as as store-and-forward network. What this means is that brokers, of which there can and most likely will be several in a given JMS topology, have an inbuilt persistence layer (store). This ensures that messages are not lost due to the application crashing. Furthermore, brokers can send messages to other brokers (forward).

Depending on the JMS implementation used brokers can usually be run in stand-alone more or embedded in your application

Transports

JMS provides, depending on the implementation used, many different means of transportation for the messages. Transports can vary from TCP sockets to HTTP-based to intra-VM communiation (thus avoiding network latency). The VM transport makes it possible for components inside a single VM to communicate with each other, therefore making it unnecessary to access objects directly.

Transports are used both for communication between clients and brokers, as well as between brokers.

Queues / Topics

When a consumer sends a message in a JMS network it usually does not have to know exactly what its intended target is. While the brokers make sure that the eventual target can receive the message, queues and topics are used to discern the recipient. With Queues a producer can send a message to an arbitrarily named queue. The consumer can then fetch messages from this queue, after which the message is removed from the queue (although there are exceptions to this rule). This is mostly equivalent to point-to-point messaging. With Topics a publish-subscribe mechanism can be realized. The consumer sends a message to a topic (publish) and all interested producers can receive this message (subscribe) thus making it a broadcast.

By default communication is uni-directional although bi-directional communication is possible. Several different message types are supported such as simple text messages, (serialized) object messages and byte streams.

Example

For my example application I implemented a system where several servers receive and process certain queries. The queries shall be logged on a central server. While there are many JMS implementations I have used Apache ActiveMQ due to the usual high quality and maturity of Apache projects and their open nature.

Topology

The topology is essentially comprised of one broker per query server (the producers), and one broker on the central server (the consumer). The brokers are embedded into the applications and the applications can run on different physical machines.

The clients use the VM transport to communicate with their local broker while the communication between the query brokers and log broker uses a TCP transport. This way no messages are lost in case of a network failure as the query brokers make sure to resume the connection to the log broker once the network connection is reestablished and resend any undelivered messages.

JMS example topology

JMS example topology

Once the consumer has received the message it can act on it depending on the business requirements, for example log it into a database for further analysis.

For the working example see JmsTest.java. To make things easier both brokers in the example reside in the same VM but still use TCP for communication. With this setup hey could just as easily run on different physical machines.

Moving on

As mentioned above JMS is a highly sophisticated API which should fulfill most requirements at the price of a steep learning curve. It integrates well with frameworks such as Spring and can be configured using XML files. Further topics include features fail-over / high availability setups, hub-and-spoke topologies, JMX support and discovery networks. Furthermore, many different implementations are available, each of which certainly has its own perks and focus.