Queues and topics

In this article by Luca Stancapiano, the author of the book Mastering Java EE Development with WildFly, we will see how to implement Java Message Service (JMS) in a queue channel using WildFly console.

(For more resources related to this topic, see here.)

JMS works inside channels of messages that manage the messages asynchronously. These channels contain messages that they will collect or remove according the configuration and the type of channel.

These channels are of two types, queues and topics. These channels are highly configurable by the WildFly console. As for all components in WildFly they can be installed through the console command line or directly with maven plugins of the project. 

In the next two paragraphs we will show what do they mean and all the possible configurations.

Queues

Queues collect the sent messages that are waiting to be read. The messages are delivered in the order they are sent and when beds are removed from the queue.

Create the queue from the web console

See now the steps to create a new queue through the web console.

  1. Connect to http://localhost:9990/
  2. Go in Configuration Subsystems/Messaging - ActiveMQ/default.

    Mastering Java EE Development with WildFly 10

  3. And click on Queues/Topics. Now select the Queues menu and click on the Add button. You will see this screen:

    Mastering Java EE Development with WildFly 10

  4. The parameters to insert are as follows:
    Name:  The name of the queue.
    JNDI Names: The jndi names the queue will be bound to.
    Durable?: Whether the queue is durable or not.
    Selector: The queue selector.
       

As for all enterprise components, JMS components are callable through Java Naming Directory Interface (JNDI). 

Durable queues keep messages around persistently for any suitable consumer to consume them. Durable queues do not need to concern themselves with which consumer is going to consume the messages at some point in the future. There is just one copy of a message that any consumer in the future can consume.

Message Selectors allows to filter the messages that a Message Consumer will receive. The filter is a relatively complex language similar to the syntax of an SQL WHERE clause. The selector can use all the message headers and properties for filtering operations, but cannot use the message content.Selectors are mostly useful for channels that broadcast a very large number of messages to its subscribers. On Queues, only messages that match the selector will be returned. Others stay in the queue (and thus can be read by a MessageConsumer with different selector).

The following SQL elements are allowed in our filters and we can put them in the Selector field of the form:

 Element  Description of the Element  Example of Selectors
 AND, OR, NOT  Logical operators  (releaseYear < 1986) AND
NOT (title = 'Bad')
 String Literals  String literals in single quotes, duplicate to escape  title = 'Tom''s'
 Number Literals  Numbers in Java syntax. They can be double or integer  releaseYear = 1982
 Properties  Message properties that follow Java identifier naming  releaseYear = 1983
 Boolean Literals  TRUE and FALSE  isAvailable = FALSE
 ( )  Round brackets  (releaseYear < 1981) OR (releaseYear > 1990)
BETWEEN Checks whether number is in range (both numbers inclusive) releaseYear BETWEEN 1980 AND 1989
Header Fields Any headers except JMSDestination, JMSExpiration and JMSReplyTo JMSPriority = 10
=, <>, <, <=, >, >= Comparison operators (releaseYear < 1986) AND (title <> 'Bad')
LIKE String comparison with wildcards '_' and '%' title LIKE 'Mirror%'
IN Finds value in set of strings title IN ('Piece of mind', 'Somewhere in time', 'Powerslave')
IS NULL, IS NOT NULL Checks whether value is null or not null. releaseYear IS NULL
*, +, -, / Arithmetic operators releaseYear * 2 > 2000 - 18

Fill the form now:

In this article we will implement a messaging service to send coordinates of the bus means . The queue is created and showed in the queues list:

Mastering Java EE Development with WildFly 10

Create the queue using CLI and Maven WildFly plugin

The same thing can be done with the Command Line Interface (CLI). So start a WildFly instance, go in the bin directory of WildFly and execute the following script:

bash-3.2$ ./jboss-cli.sh
You are disconnected at the moment. Type 'connect' to connect to the server
or 'help' for the list of supported commands.
[disconnected /] connect
[standalone@localhost:9990 /] /subsystem=messagingactivemq/
server=default/jmsqueue=
gps_coordinates:add(entries=["java:/jms/queue/GPS"])
{"outcome" => "success"}

The same thing can be done through maven. Simply add this snippet in your pom.xml:

<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>1.0.2.Final</version>
<executions>
<execution>
<id>add-resources</id>
<phase>install</phase>
<goals>
<goal>add-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<address>subsystem=messaging-activemq,server=default,jmsqueue=
gps_coordinates</address>
<properties>
<durable>true</durable>
<entries>!!["gps_coordinates",
"java:/jms/queue/GPS"]</entries>
</properties>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>del-resources</id>
<phase>clean</phase>
<goals>
<goal>undeploy</goal>
Queues and topics
[ 7 ]
</goals>
<configuration>
<afterDeployment>
<commands>
<command>/subsystem=messagingactivemq/
server=default/jms-queue=gps_coordinates:remove
</command>
</commands>
</afterDeployment>
</configuration>
</execution>
</executions>
</plugin>

The Maven WildFly plugin lets you to do admin operations in WildFly using the same custom protocol used by command line. Two executions are configured:

add-resources: It hooks the install maven scope and it adds the queue passing the name, JNDI and durable parameters seen in the previous paragraph.

del-resources: It hooks the clean maven scope and remove the chosen queue by name.

Create the queue through an Arquillian test case

Or we can add and remove the queue through an Arquillian test case:

@RunWith(Arquillian.class)
@ServerSetup(MessagingResourcesSetupTask.class)
public class MessageTestCase {
...
private static final String QUEUE_NAME = "gps_coordinates";
private static final String QUEUE_LOOKUP = "java:/jms/queue/GPS";
static class MessagingResourcesSetupTask implements ServerSetupTask {
@Override
public void setup(ManagementClient managementClient, String
containerId) throws Exception {
getInstance(managementClient.getControllerClient()).createJmsQueue(QUEUE_NA
ME, QUEUE_LOOKUP);
}
@Override
public void tearDown(ManagementClient managementClient, String
containerId) throws Exception {
getInstance(managementClient.getControllerClient()).removeJmsQueue(QUEUE_NA
ME);
}
}
Queues and topics
[ 8 ]
...
}

The Arquillian org.jboss.as.arquillian.api.ServerSetup annotation let to use an external setup manager used to install or remove new components inside WildFly. In this case we are installing the queue declared with the two variables QUEUE_NAME and QUEUE_LOOKUP.

When the test ends, automatically the tearDown method will be started and it will remove the installed queue.

To use Arquillian it's important add the WildFly testsuite dependency in your pom.xml project:

...
<dependencies>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-testsuite-shared</artifactId>
<version>10.1.0.Final</version>
<scope>test</scope>
</dependency>
</dependencies>
...

Going in the standalone-full.xml we will find the created queue as:

<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
<server name="default">
...
<jms-queue name="gps_coordinates" entries="java:/jms/queue/GPS"/>
...
</server>
</subsystem>

JMS is available in the standalone-full configuration. By default WildFly supports 4 standalone configurations. They can be found in the standalone/configuration directory:

  • standalone.xml: It supports all components except the messaging and corba/iiop
  • standalone-full.xml: It supports all components
  • standalone-ha.xml: It supports all components except the messaging and corba/iiop with the enabled cluster
  • standalone-full-ha.xml: It supports all components with the enabled cluster

To start WildFly with the chosen configuration simply add a -c with the configuration in the standalone.sh script. Here a sample to start the standalone full configuration:

./standalone.sh -c standalone-full.xml

Create the java client for the queue

See now how create a client to send a message to the queue. JMS 2.0 simplify very much the creation of clients. Here a sample of a client inside a stateless Enterprise Java Beans (EJB):

@Stateless
public class MessageQueueSender {
@Inject
private JMSContext context;
@Resource(mappedName = "java:/jms/queue/GPS")
private Queue queue;
public void sendMessage(String message) {
context.createProducer().send(queue, message);
}
}

The javax.jms.JMSContext is injectable from any EE component. We will see the JMS context in details in the next paragraph The JMS Context.

The queue is represented in JMS by the javax.jms.Queue class. It can be injected as JNDI resource through the @Resource annotation.

The JMS context through the createProducer method creates a producer represented by the javax.jms.JMSProducer class used to send the messages. We can now create a client injecting the stateless and sending a string message hello!

...
@EJB
private MessageQueueSender messageQueueSender;
...
messageQueueSender.sendMessage("hello!");

Summary

In this article we have seen how to implement Java Message Service in a queue channel using web console, Command Line Interface and Maven WildFly plugins, Arquillian test cases and how to create Java clients for queue.

Resources for Article:


Further resources on this subject:


You've been reading an excerpt of:

Mastering Java EE Development with WildFly

Explore Title