MQ

 View Only

Deploying a Message Driven Bean in Open Liberty with IBM MQ

By Anthony Beardsmore posted Tue September 08, 2020 05:52 AM

  

Who is this for?

This is intended to be a beginner’s guide for those familiar with MQ but less so with Java EE, Open Liberty, JCA etc.  You might for example be an MQ administrator who has been approached by a Java application developer saying “I’ve created this component in my development environment and it needs to hook up to MQ - how do we deploy it?".  Most of the general ideas discussed here would apply whatever MDB container you are deploying to, but the examples I've used are all based on deploying into Open Liberty specifically.

Although I've worked on and with IBM MQ for many years, my experience with JMS and application server configuration was relatively limited - and specifically when I came to try and configure OpenLiberty I found it hard to track down the exact details I needed.  Therefore it seemed worth sharing what I've learned with anyone else who may be in the same position.

What is Open Liberty?

Open Liberty is described as an application development framework – it’s a free and open source server environment for developing and deploying Java applications, which provides all sorts of tools and facilities to prevent you having to reinvent the wheel in your application code.  For the purposes of this guide, the thing which we are most interested in is that it provides a Jakarta EE (8) server environment.

If you’re looking around in this area, you’ll probably come across references to ‘WebSphere Application Server’, ‘WebSphere Liberty Profile’ and ‘Open Liberty’.  You can find much more information about these options elsewhere, but as a very brief summary:

  • WebSphere Application Server (WAS) – IBM’s traditional Java EE application server, extremely flexible, scalable and full featured. Sometimes referred to as ‘traditional’ WAS.
  • WebSphere Liberty Profile (WLP) – a newer, related but separate runtime providing many of the same facilities, specifically designed to be lightweight and composable – so for example, if you do not require the full Java EE specification you do not need to deploy all of these features.
  • Open Liberty – the free and open source ‘upstream’ source for WLP, contributed to the community by IBM.

Since Open Liberty is freely available to all and this is where most active development of new features takes place, I’ve chosen to work with this for this example.  By its nature, Open Liberty is slightly more ‘bleeding edge’ than the other environments mentioned, which can also mean how to guides and documentation are harder to find for some specific features – this was another driver for documenting what I found here.

Note that because WLP/Open Liberty are intended to be lightweight and composable, they are well suited for deployment in modern container environments, and microservice patterns.  This is another reason it may be increasingly important to be able to connect a Liberty based application/service into your MQ infrastructure.

What’s a Message Driven Bean (and why would I want one)?

This isn’t the place for a full history of Java Enterprise Edition (or Jakarta EE as it is now known), and there are plenty of resources out there for that.  If you are reading this, you’re probably already aware of Jakarta EE and JMS – the Java Messaging Service API which forms part of the Java application server environment.  Jakarta EE servers typically provide a simple messaging service out of the box, but to support more complicated or full featured messaging infrastructure provide connectivity out to other messaging servers – such as MQ – via ‘Resource Adapters’ (more on this below).

A typical way of deploying server side messaging applications into a Jakarta EE server is as a ‘Message Driven Bean’ (MDB) – this abstracts away a lot of the ‘glue’ required to communicate with your messaging service, and leaves a developer to implement just the code executed when a message arrives on a specific destination. 

Creating an MDB essentially just means defining a Java class with a few special characteristics – in particular, an ‘OnMessage’ method – and your IDE or online tutorial of choice will help you get started.  There is also a conveniently packaged IVT (installation verification test) application specifically for the IBM MQ Resource Adapter – if you don’t want the hassle of creating your own, this is a good place to start.

A few other general notes and pointers:

Most Open Liberty guides out there start by assuming familiarity with Maven.  If you are going to be doing a lot of Java/JMS development, it’s worth familiarising yourself with this tool, as it’s an extremely popular way of managing Java builds and runtime dependencies, but that’s a whole other topic.  It’s perhaps my lack of expertise in Maven, but I actually found that for me it muddied the waters while configuring my MDB (when something went wrong, I was often wondering whether it was my Maven configuration or Liberty deployment that had the issue), so as you’ll see below I configured things here manually – if you are comfortable working with Maven, I’m sure you’ll have no problem implementing the same pattern via your POM.

To get Liberty to talk to MQ, you need to get the ‘resource adapter’ from somewhere.  If you are using Maven (or even if you aren’t), these can be pulled from the Maven central repository to which IBM uploads all required jar files, but you can also download directly from IBM at FixCentral.  This also goes for the IVT application/MDB I mentioned earlier.

A key difference for our use case between Open Liberty and WebSphere Liberty Profile is that the former only has a generic ‘JMS’ feature, nothing IBM MQ specific, where WLP comes with some MQ support out of the box.  Configuring the ‘generic’ resource adapter is the biggest hurdle to clear to get all of this working, but once you know what you are doing there this doesn’t present any big problems. 

Configuring MQ

This isn’t really the focus of this article, but we need a few MQ artifacts before we get started.  For the examples below, I’ve assumed the existence of a queue manager called ‘LibTest’, with a listener configured on 1414, SYSTEM.DEF.SVRCONN available, and no channel or connection security configured.  I’ve also defined a single local queue called ‘TESTQ’.

Configuring Liberty

As mentioned above, there are various ways to automate parts of the setup process but I chose to download and install Open Liberty manually from https://openliberty.io/).  I installed the Jakarta EE 8 package – probably including far more features that I really needed.

 

Once Liberty is installed somewhere (basically just an unzip) you can create a server and start it (in foreground mode) with

<installdir>/bin/server create <name>

and

<installdir>/bin/server run <name>

(To stop the server, just hit ctrl-c to bring the JVM down in a controlled manner.  You can also run your server in other modes – background, developer etc. with variants of this command).

Creating the server will lay down a default server configuration in <installdir>/usr/servers/<name> including a server.xml.

The server.xml is the one stop shop for configuring a Liberty server.  Generally, Liberty takes the approach that most configuration can be defaulted, and you only need to define the ‘extras’ here.  This is where we are going to put the bits and pieces needed to wire up our MDB to Liberty, and Liberty to our IBM MQ installation.

 

The first thing we need to do is give Liberty a way to ‘find’ IBM MQ.  Jakarta EE provides a pluggable framework for back end services (JCA) and this is the preferred way of introducing the two servers to one another.  This is called a ‘Resource Adapter’ and can be downloaded from Maven or IBM FixCentral – at the time of writing the latest available was 9.1.5 so I fetched wmq.jmsra-9.1.5.0.rar and put this somewhere convenient on my local filesystem.

To tell Liberty where to find the RA, we just need something like the following:

    <resourceAdapter id="mqJms" location="[path_to_lib]/lib/wmq.jmsra-9.1.5.0.rar"/>

Note that the ‘id’ for the resource adapter can be almost anything you like – EXCEPT the reserved values ‘wmqJms’ and ‘wasJms’.  See https://www.ibm.com/support/knowledgecenter/SSFKSJ_latest/com.ibm.mq.dev.doc/q120040_.htm for more information.  Whatever value you use here, just make sure you use the same below when configuring the ‘properties’ on the other objects.

 

Now we need to give Liberty some information about the MDB we want it to host.  Properties for Jakarta EE objects can often be defined in multiple ways, partly a reflection to updates to the specification over the years.  Nowadays, it’s likely that ‘fixed’ attributes will be defined in the Java class itself by the developer (using annotations), but ‘deployment’ attributes are specified here in the server configuration.

For the IVT sample, we need to provide an activation spec to Liberty telling it about the class which implements our bean, and some of the runtime information it needs to use to connect to MQ. 

    <jmsActivationSpec id="wmq.jmsra.ivt-9.1.5.0/WMQ_IVT_MDB/WMQ_IVT_MDB">
        <properties.mqJms transportType="CLIENT"
            destinationRef="jms/IVTQueue" destinationType="javax.jms.Queue"
            hostName="localhost" port="1414"
            channel="SYSTEM.DEF.SVRCONN" queueManager="LibTest"/>
    </jmsActivationSpec>

TIP1: you can also refer to other JNDI object definitions if they exist for the destination and connection information to avoid typing it twice, using the connectionFactoryLookup and destinationLookup properties.  For example, since we are defining a connectionFactory later in this example (see below), we could avoid explicitly including the hostname, port, channel, and queue manager properties here on the activation spec.  I’ve chosen to use the ‘longhand’ form here however for clarity.

TIP2: In this example, we could actually even have omitted the hostname, port, and channel attributes entirely.  As with most Liberty configuration, the resource adapter will default to ‘standard’ values if none are explicitly provided – in this case, the values we have used for all three are in fact the defaults.

 

For many MDBs, the above would be all the configuration needed (and not all of these attributes would be required if hard coded in annotations.)  Our MDB however also wants the queue it listens on to be explicitly defined, which we can do as follows:

    <jmsQueue id="jms/IVTQueue" jndiName="IVTQueue">
     <properties.mqJms
        baseQueueName="TESTQ"
        baseQueueManagerName="LibTest"/>
    </jmsQueue>


Finally, the IVT MDB also requires an outgoing connection (after it receives messages, it sends them on as a response).  For this, JMS requires an object called a ‘connection factory’ – it’s serving a similar purpose to the activation spec, but in this case will be referenced by the code itself when it needs a way to send messages, rather than by the application server when waiting to receive.

The connection factory and its ‘connection pool’ referenced by the sample, needs to look like this:

    <connectionManager id="MyConMgr" maxPoolSize="10"/>

     <jmsConnectionFactory jndiName="IVTCF" connectionManagerRef="MyConMgr">
        <properties.mqJms transportType="CLIENT"
            hostName="localhost" port="1414"
            channel="SYSTEM.DEF.SVRCONN" queueManager="LibTest"/>
    </jmsConnectionFactory>

 

For the full list of objects and properties which can be configured when deploying a JMS application, see https://www.ibm.com/support/knowledgecenter/SSFKSJ_latest/com.ibm.mq.dev.doc/q031650_.htm - in particular the ‘Configuring for Inbound Communication’ and ‘Configuring for Outbound communication’ topics.

Deploying the application to Liberty – and trying it out!

Whenever you make changes to the server.xml file, you will see Liberty immediately read the new configuration and try to act on it.  If you’ve been doing that as you go along, you probably have various errors by now about not being able to find our MDB.

The missing piece of the puzzle is to take the application you want to deploy (in this case, the IVT EAR file, which includes our MDB and a simple web application to test it) and simply place it in the ‘dropins’ subdirectory of your server configuration.  Liberty will immediately unpack and deploy the application (you can also restart Liberty at any time to force re-reading the config, which is required for certain types of changes.)

All done!  You should be able to test your deployed application and MDB at http://localhost:9080/WMQ_IVT/

Thanks - and further reading:

All credit due to Colin Paice, for this incredibly helpful similar article focused on WLP rather than OpenLiberty.

https://colinpaice.blog/2018/12/03/getting-ibm-jms-samples-working-in-a-was-libery-web-server-on-ubuntu-for-people-who-cannot-spell-java-massage-service/

Other links you may find useful:
- Keep up with the latest blogs by joining the MQ Community
- For documentation, visit the MQ Knowledge Center
- New to MQ? Learn MQ at IBM Developer
- Want the product page? It's here



#IBMMQ
#MQ
#OpenLiberty
0 comments
34 views

Permalink