Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

WAS Liberty and JMS Messaging

DZone's Guide to

WAS Liberty and JMS Messaging

The built-in facilities of WAS Liberty, which provides support for JMS messaging, can be used in a multi-server setup.

· Integration Zone
Free Resource

Migrating from On-Prem to Cloud Middleware? Here’s what Aberdeen Group says leading companies should be considering. Brought to you in partnershp with Liaison Technologies

WAS Liberty provides support for JMS messaging thanks to JEE 6 and 7, built-in JMS support, and support for Websphere MQ.

In this article, I will show you how to use the built-in facilities using a multi-server setup (separate JMS messaging server). I will be covering these topics:

  • Setting up the JMS messaging engine on a separate WAS Liberty server.

  • Setting up a server for a JMS client application, including MDB usage.

  • Sample code to connect to and send a topic message and discuss MDB usage.

Before you continue, if you're new to WAS Liberty profile or want to refresh yourself on the basics, please have a look at this article.

Multi-Server JMS Configuration

WAS Liberty supports JMS via features enabled on the application servers. These features come as part of a WAS Liberty Runtime that supports those JEE features.

The diagram below assumes a full JEE 7 runtime, but you can use a Liberty runtime like the web profile. Just make sure you have the JMS features installed.

Multi-server JMS with WAS Liberty

In order for a JMS Topic (and queue) to work, you need the following parts.

On the JMS messaging engine’s server:

  • A messaging engine with a topic and/or queue space. A topic or queue space is a grouping of topics or queues with the same reliability, ordering, persistence, and other requirements.

  • A JMS endpoint so that other servers can connect to the server with the messaging engine (this is not needed if the JMS application is on the same server as the messaging engine).

You need the following on the server where the JMS application is deployed:

  • A JMS topic or queue connection factory that allows you to connect to and use the JMS facilities.

  • A connection manager to allow connection pooling for the connection factory.

  • A topic or queue definition listing the topic and queue space and remote topic and queue name you want to connect to, including the connection information;

  • Optionally, an activation specification if you want to use MDBs to process incoming messages.

In your JEE application, the connection factory and queue or topic are then looked up and used via JNDI.

Create the JMS Messaging Engine Server

I’m assuming you already have a JEE 7-featured WAS Liberty Runtime installed. If not, please refer to my other article

From <WAS Liberty Runtime installation dir>/wlp/bin:

server create jms-messaging-engine 

Browse to the newly created server (/wlp/usr/servers/jms-messaging-engine) and edit the server.xml file to look something like this:

<server description="JMS Messaging Engine Server">
     <!-- Enable features for WAS JMS Server -->
     <featureManager>
         <feature>wasJmsServer-1.0</feature>
     </featureManager>

 <!-- The variables below can be added to bootstrap.properties -->
     <wasJmsEndpoint id="InboundJmsCommsEndpoint"
 host="${host}"
 wasJmsPort="${wasJmsPort}"
 wasJmsSSLPort="${wasJmsSSLPort}" />

 <!-- Create a custom topic space with no persistence and ordering prefs. -->
 <messagingEngine>
 <topicSpace id="ExpressNonPersistent.Topic.Space"
 forceReliability="ExpressNonPersistent"
 maxMessageDepth="5000"></topicSpace>
 </messagingEngine>

<!-- Other config goes here -->
 </server>

wasJmsServer-1.0

To use the messagingEngine and the default JMS messaging provider, add this feature.

wasJmsEndpoint

When you want external servers to communicate to this server via JMS, you add this configuration. Note the host and port, as you will need this on the other server(s).

messagingEngine

Specify the messaging engine. You can optionally specify your own queue and topic spaces in here.

topicSpace

I’ve created a custom topic space for the demo app with an express, non-persistent reliability. This simply passes messages through and doesn’t keep them.

A note on the topicSpace tag: By default, WAS Liberty provides two default spaces: Default.Queue.Space and Default.Topic.Space. These default to persistent reliability.

Create the JMS Client Server

From <WAS Liberty Runtime installation dir>/wlp/bin:

 server create jms-client-server 

Go to the server (/wlp/usr/servers/jms-client-server) and edit the server.xml file so it looks like this:

<server description="JMS client server">
    <!-- Enable features -->
    <featureManager>            
        <feature>jndi-1.0</feature>       
        <feature>jms-2.0</feature>
        <feature>mdb-3.2</feature>
        <feature>wasJmsClient-2.0</feature>
    </featureManager>

<jmsTopicConnectionFactory 
jndiName="jms/TCF" 
connectionManagerRef="ConMgr1"
clientID="jmsClient1">
    <properties.wasJms
      remoteServerAddress="${wasJmsRemoteHost}:${wasJmsPort}:BootstrapBasicMessaging"
      />
</jmsTopicConnectionFactory>
<connectionManager id="ConMgr1" maxPoolSize="2"/>

<jmsTopic id="myResponseTopic" jndiName="jms/myResponseTopic">
    <properties.wasJms topicName="MyResponses"
      topicSpace="ExpressNonPersistent.Topic.Space"
      deliveryMode="NonPersistent" 
      timeToLive="60000" 
      priority="1"
      readAhead="AsConnection"
       />
</jmsTopic>
<!-- the variables below can be added to bootstrap.properties -->
<jmsActivationSpec id="${appLocation}/MyEJBModule/MyMDBClassName">
    <properties.wasJms 
    destinationRef="myResponseTopic" 
    destinationType="javax.jms.Topic"
    remoteServerAddress="${wasJmsRemoteHost}:${wasJmsPort}:BootstrapBasicMessaging"/>
</jmsActivationSpec>

<!-- Other config goes here -->
</server>

Features

The only feature really needed is the wasJmsClient feature; the other features enable usage of MDBs.

NB

It’s really important to add the MDB feature and not just JMS; the server will not give an error but your MDB won’t work.

jmsTopicConnectionFactory

  • jndi name will be used as-is or via a resource env entry in your application.

  • connectionManagerRef points to the connection manager.

  • clientID can be any value that uniquely identifies this client server.

  • remoteServerAddress points to the JMS messaging engine server we created earlier. The BootstrapBasicMessaging part indicates that we’re doing a non-secure HTTP call and is the name of the messaging bootstrap transport chain to use. Other examples are BootstrapSecureMessaging (secure port)/SSL or BootstrapSecureTunneledMessaging (secure port/SSL using HTTP wrappers).

jmsTopic

This describes the topic to connect to. Note that this topic doesn’t necessarily exist on the JMS messaging engine server; it is created on the fly if it doesn’t exist. The wasJms properties specified need to match up with a declared topic space on the messaging engine server. Notably, the deliveryMode has to match the topicSpace’s settings.

jmsActivationSpec

If you plan on using a message bean, you declare an activation spec so that messages can be delivered to the MDB.

  • The id needs to be in the form application name/module name/bean name. In the example above, you can replace the variable ${appLocation} with the folder or name of the EAR (or WAR), which is relative to the <server root>/apps> folder. If you’re deploying a WAR, you can omit the module name.
  • destinationRef points to the definition of the topic we did earlier.
  • remoteServerAddress is the same as used in the connection factory.

Using It in Your Code

Sending Messages

This is how you can send messages from your Java code to the topic (from somewhere in your code):

TopicConnectionFactory topicConnectionfactory;
Topic topic;
try {
  topicConnectionfactory = (TopicConnectionFactory) InitialContext.doLookup(“java:comp/env/jmsTCF”);
  topic = (Topic) InitialContext.doLookup(“java:comp/env/myResponseTopic”);
} catch (NamingException e) {
  LOG.log(Level.SEVERE, "Could not look up JMS Topic Connection Factory/Topic: " + e.getMessage(), e);
  return;
}

try (TopicConnection topicConnection = topicConnectionfactory.createTopicConnection()) {
  topicConnection.start();    
  TopicSession topicSession = topicConnection.createTopicSession(false,  javax.jms.Session.AUTO_ACKNOWLEDGE);    
  TopicPublisher topicPublisher = topicSession.createPublisher(topic);

  topicPublisher.publish(topicSession.createTextMessage(“Hello world”));
} catch (JMSException e) {
  LOG.log(Level.SEVERE, "Could not send JMS message to the required topic due to: " + e.getMessage(), e);
}

This code assumes you’re using resource env entries, but you can also look it up directly.

Receiving Messages

To listen to messages from the topic in an MDB, simply create an MDB as per JEE spec, implementing the onMessage method. Note the name of this MDB and replace it, together with the app and module name (if applicable) in the server.xml in the form application name/module name/MDB class name".

Test Everything

You should be able to start both servers up (server start <servername>). If you find that messages aren't coming through, verify that both servers started successfully and your JMS port and server names match.

Other issues might be that the queue or topic definition in the JMS application's server does not match an available topic or queue space on the messaging engine. This includes the delivery mode and other settings.

If everything seems OK but the message bean is not receiving messages, verify that the activation spec points to the MDB in the correct format and that the MDB feature is listed on the server.

Conclusion

In this article, we looked at setting up a JMS messaging engine in a separate WAS liberty server than that of the application. We focused on the server.xml files for these servers, highlighting some important settings.

We also looked at a small sample on how to call into the topic from Java and noted you can add a normal JEE MDB, provided that the naming convention is honored in the server.xml to receive messages.

Resources

Liberty Server Configuration: the menu lists details on all the tags available in server.xml, including jmsTopic and jmsQueue;

Liberty profile embedded JMS messaging provider;

Confguration elements in the server.xml file;

List of WAS Liberty server features;

Simplified JMS Messaging Support for Liberty Profile pdf.

Is iPaaS solving the right problems? Not knowing the fundamental difference between iPaaS and iPaaS+ could cost you down the road. Brought to you in partnership with Liaison Technologies.

Topics:
integration ,runtime ,was liberty ,jms messaging

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}