Getting IBM JMS samples working in a WAS Libery Web Server on Ubuntu for people who cannot spell Java Massage Service.

Why these JMS blog posts?

I had a “quick” question from someone, “can I configure JMS to reduce CPU usage and improve performance?”. It was was wet Monday in Orkney (north of Scotland) and I thought I would spent an hour looking into it. A few weeks later, I am much wiser, and have some answers to the question. The Knowledge Centre has a lot of information, mostly is useful, mostly accurate, some information is missing and some assumes that you are very familiar with the product.

I also found that that the Java people tend to use different words for familiar concepts, so I had to struggle with this different language.

Below are the blog posts I wrote on getting JMS working on Ubuntu 18.04 with MQ V9.

This section builds on “Getting JMS samples working in batch on Ubuntu for people who cannot spell Java Massage Service” entry

What is a WAS Liberty server?

A WAS liberty server is a cut down version of a full function WAS server. You configure it by specifying information in a server.XML file.

I downloaded wlp-webProfile8-18.0.0.3.zip and unziped it into ~/wlp

Dont throw away your zip file… as you may need it if you make a mess of your configuration!

Create a server instance called test. (The WAS people call this a profile… another example of the strange language used by these Java people). See Setting up Liberty for more information

cd wlp
cd bin
./server create test

You can run the server in background using

./server start test

The messages go to a file in ~/wlp/usr/servers/test/logs

or run it in foreground using

./server run test

The messages come out in your terminal’s window, so it is easy to see the effects of changes to your configuration.

You can use ctrl-c to stop the server started with ./server run …

If you started the server with ./server run test, or ./server start test, you can stop it by running

./server stop test

in a different terminal window.

Note: If you stop the server it gives a message

CWWKE0036I: The server test stopped after 1 minutes, 43.709 seconds.
If you try to restart it, within a few seconds, it may give a message

CWWKE0055I: Server shutdown requested on Tuesday, 27 November 2018 at 17:02. The server test is shutting down.
I use Ctrl-C and it stops quicker.

If you wait for a short period( 10 seconds) it seems to start up OK.

Configure the server

In the directory (where ‘test’ is the name of my server) ~/wlp/usr/servers/test is a file server.xml

This contains the configuration for the instance. I added some statements to this file before configuring it for JMS.  The following is my initial server.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>webProfile-8.0</feature>
</featureManager>
<!-- Define an Administrator and non-Administrator -->
<basicRegistry id="basic">
<user name="admin" password="adminpw" />
<user name="nonadmin" password="nonadminpwd" />
</basicRegistry>
<!-- Assign 'admin' to Administrator -->
<administrator-role>
<user>admin</user>
</administrator-role>
<!-- To access this server from a remote client add a host attribute to
the following element, e.g. host="*" -->

<httpEndpoint id="defaultHttpEndpoint" httpPort="9080" httpsPort="9443"/>
</server>

This defines userid admin and password adminpw, and says that user admin is an administrator.

You use port 9080 to access it non securely, and port 9443 for an SSL, or a secure session.

The statements

<featureManager>
<feature>webProfile-8.0</feature>
</featureManager

specify which components are to run in the server. The feature webProfile-8.0 copies in other features.

Save this file.

cd  ~/wlp/bin

execute  ./installUtility install test

Thisreads the server.xml anddownloads the files needed by the test instance,if they are not already installed.  I did a lot of playing around trying to get the Liberty instance to work as I expected.

{When things did not work as I expected, I did the following to ensure I had a clean environment

  1. copied out the server.xml file,

  2. removed the ~/wlp directory (which deletes the server.xml file)

  3. unzipped the file again to recreate the wlp directory

  4. cd wlp.bin, ./server create test

  5. copy the server.xml file back

  6. run ./installUtility install test

  7. copy the file to dropin- see below

}

Start the server  ./server run test

This produced

colinpaice@colinpaice:~/wlp/bin$ ./server run test
Launching test (WebSphere Application Server 18.0.0.3/wlp-1.0.22.cl180320180905-2337)
on OpenJDK 64-Bit Server VM, version 10.0.2+13-Ubuntu-1ubuntu0.18.04.2 (en_GB)

[AUDIT ] CWWKE0001I: The server test has been launched.
[AUDIT ] CWWKE0100I: This product is licensed for development, and limited production use.
The full license terms can be viewed here: https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/license/base_ilan/ilan/18.0.0.3/lafiles/en.html

[AUDIT ] CWWKZ0058I: Monitoring dropins for applications.
[AUDIT ] CWPKI0820A: The default keystore has been created using the 'keystore_password'
environment variable.

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.apache.aries.jndi.startup.Activator (file:/home/colinpaice/wlp/lib/com.ibm.ws.org.apache.aries.jndi.core_1.1.22.jar) to field javax.naming.spi.NamingManager.initctx_factory_builder
WARNING: Please consider reporting this to the maintainers of org.apache.aries.jndi.startup.Activator
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
[AUDIT ] CWWKF0012I: The server installed the following features: [beanValidation-2.0, servlet-4.0, ssl-1.0, jndi-1.0, cdi-2.0, jdbc-4.2, osgiConsole-1.0, appSecurity-3.0, appSecurity-2.0, jaxrs-2.1, monitor-1.0, webProfile-8.0, jpa-2.2, jsp-2.3, jsonb-1.0, ejbLite-3.2, managedBeans-1.0, jsf-2.3, localConnector-1.0, jsonp-1.1, jaxrsClient-2.1, el-3.0, jpaContainer-2.2, jaspic-1.1, distributedMap-1.0, websocket-1.1].
[AUDIT ] CWWKF0011I: The server test is ready to run a smarter planet.

The statement
CWWKF0012I: The server installed the following features: [beanValidation-2.0, servlet-4.0, ssl-1.0, jndi-1.0,…, websocket-1.1]

shows you what <feature>…</feature> were included. <feature>webProfile-8.0</feature> included beanValidation-2.0, servlet-4.0 etc

See Liberty features  for a description and more information about them.

Enter http://localhost:9080/ into the URL of a web browser. A page should be displayed.

In the Liberty startup it should have displayed a url like

http://10.0.0.59:9080/adminCenter/

use this in the web browser.

sign on with the userid specified (admin) and password
I got 3 boxes

  • Explore

  • Server config

  • wasdev.net

I originally had problems using the Explore and Server Config functions.  If I used /usr/lib/jvm/java-11-openjdk-amd64/bin/java then I got “Just a minute” and a blue box. Sometimes I got past this and I was given a link “server.xml” to click. This gave me “Just a minute”, and I was unable to get past this and display the configuration.

A week or so later I changed java levels and then the server started, and I could work with the server.xml file.

I reverted back to the openjdk version of java ( java -version)

openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-1ubuntu0.18.04.1-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)

and this also worked. I cannot explain why it didn’t work, and then a few weeks later it did work!  It has stopped working again.

Configuring your Liberty instance

You can use the web panels to configure the server, or you can edit the server.xml.

You may want to use the liberty web pages for initial configuration and exploration, but then use the server.xml file, so you can put common or shared data in their own file, and use change management on these files.

I’ve used the server.xml route in the rest of the section.

Adding the JMS components.

Shut down the liberty instance, either use Ctrl-c or issue the command ./server stop test.

The server needs access to the IBM MQ JMS resource adapter(RA). This is the code between the applications and the queue manager. It may already be in your MQ libraries.

If ls /opt/mqm/java/lib/jca shows two files, wmq.jmsra.ivt.ear wmq.jmsra.rar , you have the component installed.  If not, or you need a later version, you need to install it.

You can use the command jar -tvf /opt/mqm/java/lib/jca/wmq.jmsra.rar to show the dates of the files within the Resource Adapter. My files had a date of Mon Jul 09 … 2018.

Downloading the Jms Resource Adapter(RA)

See Installing the IBM MQ resource adapter and Installing the resource adapter in Liberty.

I downloaded the Resource Adapter from  Fix Central

I used java -jar ~/snap/firefox/common/Downloads/9.1.0.0-IBM-MQ-Java-InstallRA.jar

make a note of where the files are installed – by default this is directory wmq in your current working directory

You will have two files

  • wmq.jmsra.ivt.ear this is the installation verification program

  • wmq.jmsra.rar in the directory this is the Jms Resource Adapter (RA)

Contents of the JMS sample wmq.jmsra.ivt.ear

The wmq.jmsra.ivt.ear has two programs inside it.

  1. A program you can execute from a web URL, for example http://localhost:9080/WMQ_IVT/ This has logic

    1. connect to MQ –  create connection factory object using passed JNDI connection factory name – or default to IVTCF,

    2. open the queue – create destination object using passed JNDI destination name or default IVTQueue

    3. create temporary dynamic reply_to_queue

    4. set message property JNDI_CF to the JNDI connection factory name. This is is so the back end application knows which connection factory to use.

    5. set message property IVTMessageID to the message id

    6. (put)  – send the message

    7. issue (get) receive and wait up to 10 seconds

    8. close queue

    9. end

  2. A program which runs when a message arrives. The program is a Message Driven Bean (MDB) (think triggered program). This MDB is called WMQ_IVT_MDB/WMQ_IVT_MDB

    1. When a message arrives, the listening thread invokes the MDB by passing the message into the onMessage method of the MDB.

    2. It gets the connection factory name from the message property “JNDI_CF” , or default to IVTCF if it is not present in the message

    3. Create the connection using the connection factory name

    4. locate the reply_to_ queue name from the message

    5. put a reply to the reply to queue

    6. end

This application uses by default

  1. a connection factory name of IVTCF. This maps onto queue manager name

  2. A destination IVTQueue. This maps to a queue name

  3. A temporary dynamic queue for the reply.

Once you have configured the server, you can use the url http://localhost:9080/WMQ_IVT/ to run the program, and if the MDB is active it will quickly complete, and you can display the returned message

Configuring the liberty instance

You can edit the server.xml file or use  “AdminConsole” application on the web page.

Both will update the server.xml file.

Add the JMS components to the server.xml configuration file

Add the following to the bottom of the server.xml file before the </server> tag at the bottom

<featureManager>
<!– the next two features are needed to install the JMS and MDB code –>
<feature>wmqJmsClient-2.0</feature>
<feature>mdb-3.2</feature>
</featureManager>
<!– point to the Resource Adapter(RA) – specify the value for your system –>
<variable name=”wmqJmsClient.rar.location” value=”/opt/mqm/java/lib/jca/wmq.jmsra.rar”/>
<!– tell the server where the MQ libraries are –>
<wmqJmsClient nativeLibraryPath=”/opt/mqm/java/lib64″/>
<!– connection manager is used to define connection pool sizes etc
<connectionManager id=”QMAcf” />
<!– IVT Connection factory –>
<jmsConnectionFactory connectionManagerRef=”QMAcf”
     jndiName=”IVTCF”

    id=”samplejQCF”>
   <properties.wmqJms queueManager=”QMA”
         transportType=”BINDINGS”
        applicationName=”Hello”/>
</jmsConnectionFactory>
<!– IVT Queues –>
<jmsQueue id=”IVTQueue” jndiName=”IVTQueue”>
<properties.wmqJms baseQueueName=”IVTQueue”/>
</jmsQueue>

The  executable JMS code is in wmq.jmsra.ivt.ear. You need to add this to the liberty server dropin directory

cp /opt/mqm/java/lib/jca/wmq.jmsra.ivt.ear ~/wlp/usr/servers/test/dropins/wmq.jmsra.ivt.ear

where test is the name of my server instance.

run ./installUtility install test

Restart the server

You will get additional messages

[WARNING ] CNTR4015W: The message endpoint for the WMQ_IVT_MDB message-driven bean cannot be activated because the wmq.jmsra.ivt/WMQ_IVT_MDB/WMQ_IVT_MDB activation specification is not available. The message endpoint will not receive messages until the activation specification becomes available.

[AUDIT ] CWWKT0016I: Web application available (default_host): http://localhost:9080/WMQ_IVT/

[AUDIT ] CWWKZ0001I: Application wmq.jmsra.ivt started in 1.467 seconds.

Ignore the CNTR4015W: message. The liberty instance needs some more configuration which is done below.

Note the url in the CWWKT0016I: … http://localhost:9080/WMQ_IVT/ messsage.

Enter the URL in a web browser. You should get a panel displayed

The ConnectionFactory IVTCF needs to have a matching

<jmsConnectionFactory jndiName=”IVTCF” …

statement

within this jmsQueueConnectionFactory the queue manager to use is defined with the

<properties.wmqJms queueManager="QMA" 
transportType="BINDINGS"
/>

The Destination IVTQueue needs to have a matching jmsQueue

<jmsQueue id="IVTQueue" jndiName="IVTQueue">
<properties.wmqJms baseQueueName="IVTQueue"/>
</jmsQueue>

define the queue to the queue manager using runmqsc

Define ql(‘IVTQueue’) …

You need the quotes around the queue name, because the default is an upper case queue name IVTQUEUE and you get return code 2085 when you try to run the sample! You could change it to

<properties.wmqJms baseQueueName=”IVTQUEUE”/>.

When you click on the run ivt button it issues a request with URL

http://localhost:9080/WMQ_IVT/IVT?mqcf=IVTCF&dest=IVTQueue

As the MDB is not running, the web page will wait for about 10 seconds then reports  “failed to receive response message” – this is because the MDB is not running, and so did not send a reply back.Screenshot from 2018-11-26 08-43-37

Configuring the MDB

As with MQ on CICS on z/OS, you can have a thread listening for messages on a queue, and then passing the messages to a different thread do do the work.

In the JMS environment, you can run the same way. A thread listens, and when a message arrives on the queue, it runs a Message Driven Bean passes it the message.

You need to configure JMS so it know which queue to listen on, and which MDB to run.

When the Liberty instance was started, it produced a message

[WARNING ] CNTR4015W: The message endpoint for the WMQ_IVT_MDB message-driven bean cannot be activated because the wmq.jmsra.ivt/WMQ_IVT_MDB/WMQ_IVT_MDB activation specification is not available. The message endpoint will not receive messages until the activation specification becomes available.

This was because the application is in the dropins directory. Liberty tries to process applications in this directory. It finds there are some definitions missing, and so produces the warning message.

MDBs need an Activation Specification so it knows which MQ Queue to listen to.

<jmsActivationSpec id=”wmq.jmsra.ivt/WMQ_IVT_MDB/WMQ_IVT_MDB”>…

The ID value must be in the format of application name/module name/bean name where application name is the name of the jar file (without the .jar suffix). 

See Deploying message-driven beans to connect to IBM MQ

<jmsQueue id="AAAA" jndiName="IVTQueue">
<properties.wmqJms baseQueueName="IVTQueue"/>
</jmsQueue>
<jmsActivationSpec id="wmq.jmsra.ivt/WMQ_IVT_MDB/WMQ_IVT_MDB">
<properties.wmqJms
destinationRef="AAAA"
transportType="BINDINGS"
queueManager="QMA"/>
<authData id="auth1" user="colinpaice" password="ret1red"/>
</jmsActivationSpec>

The AAAAs must match up.  The id=”wmq.jmsra.ivt/WMQ_IVT_MDB/WMQ_IVT_MDB will use queue IVTQueue.

Specify the authData for the userid and password to use.

<connectionManager id="QMAJMS" maxPoolSize="21">
<jmsConnectionFactory connectionManagerRef="QMAJMS" jndiName="IVTCF" id="samplejQCF">
<authData user="colinpaice" password="ret1red"
 <properties.wmqJms queueManager="QMA"                       
     transportType="BINDINGS"
   />
</jmsConnectionFactory>

(Since I got this working I found that the queueManager=”QMA” is ignored because the sample application has a hard coded “use connectionFactory IVTCF”. If the configuration does not have this specified, then the queueManager=.. is needed)

If you now enter the http://localhost:9080/WMQ_IVT/ URL in a web browser, if all is working you should get all ticks.Screenshot from 2018-11-26 08-54-41

If you click on View Message Contents it shows the message content.

Phew after all that work – it works!

How can I see what is going on ?

I could not find much to tell me what was going on, and providing useful information. From a performance perspective I am interested in the number of threads being used by the connections pool.

You can use an external program called jconsole, which comes in your Java environment, to look within the server.

Stop your server

Add the following statements to your server.xml

<featureManager>
<feature>localConnector-1.0</feature>
<feature>monitor-1.0</feature>
<feature>jsp-2.3</feature>
<feature>osgiConsole-1.0</feature>
</featureManager>

run ./installUtility install test

restart your server

If you do not have jconsole it can be downloaded eg sudo apt install openjdk-8-jdk

type jconsole 

Screenshot from 2018-11-26 08-19-34

Click Connect.
MBeans
WebSphere → com.ibm.ws.jca.cm.mbean.ConnectionManagerMbean
→IVTCF
→ connectionManager[QMAJMS]
→operations
→ showPoolContents

It is the line under WebSphere which does not have an icon at the front of the line.

Screenshot from 2018-11-26 08-41-51

One thought on “Getting IBM JMS samples working in a WAS Libery Web Server on Ubuntu for people who cannot spell Java Massage Service.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s