Message Queues can be used for a vast amount of problems, from establishing worker processes to managing load on expensive resources. But, how can you effectively use WebSphere MQ with WebSphere Application Server? Let’s find out!
This tutorial assumes you already have WebSphere Application Server installed, and either have WebSphere MQ installed or have it accessible. If you still need WebSphere Application Server, click here to grab WebSphere Application Server for Developers. If you need WebSphere MQ, grab WebSphere MQ v8 for Developers from here.
To demonstrate this, we’ll start with a simple “Hello World” with a basic servlet and an MDB, then move to a full blown Spring application.
Preparing WebSphere MQ
To simply the tutorial, I am running WebSphere MQ locally. If you are going to leverage an instance that is already configured and running, just skip ahead.
I already have the mqm user and group, but I will add my user to the mqm group as well:
sudo usermod -a -G mqm craig
Next, I’ll create a new Queue Manager called TUTORIALQM and start the TCP listener. You can use MQExplorer to do this, or do the following:
/opt/mqm/bin/crtmqm -u DLQ TUTORIALQM
/opt/mqm/bin/runmqlsr -m TUTORIALQM -t TCP &
Creating the Queues for the Tutorial
To keep it simple, I’ll just start with two queues: REQ.HELLO and RESP.HELLO (for my Hello World requests and responses). You may choose to use MQExplorer to do this, or do the following:
DEFINE QLOCAL ('REQ.HELLO') +
DEFINE QLOCAL ('RESP.HELLO') +
/opt/mqm/bin/runmqsc TUTORIALQM < queuedefs.conf
Preparing WebSphere Application Server
Now that the queues are ready to go, we can startup WebSphere and configure our queues.
Enter a name and JNDI name, I will use Activation_Hello and jms/Activation_Hello
Enter the destination queue’s JNDI name (the request queue JNDI name we defined earlier, jms/Request_HelloQueue) and click Next
Select “Enter all the required information into the wizard” and click Next
Enter the Queue Manager name TUTORIALQM and click Next
Enter the hostname and port for MQ (localhost, 1414) and complete the wizard
Save the WebSphere configuration
A Basic Example Application
Before we get into a full application, let’s create a simple JSP + servlet and a Message-Driven Bean to demonstrate the basics.
To get started, create an EAR in Eclipse/RAD/RSA called BasicExample, a Dynamic Web Project called BasicExampleWeb, and an EJB Project called BasicExampleEjb (or clone my GitHub repository for the basic example and follow along).
Preparing the Web Application
First, we need to add our Queues and Connection factory to the IBM Web Binding XML file (ibm-web-bnd.xml in WEB-INF). The goal is to have our JNDI names available to the web resource, but allow us to change them in the application server if necessary.
Click Add and select “Message Destination Reference”
Enter jms/Request_HelloQueue into both Name and Binding Name
Click Add and select “Message Destination Reference”
Enter jms/Response_HelloQueue into both Name and Binding Name
Click Add and select “Resource Reference”
Enter jms/HelloConnectionFactory into both Name and Binding Name
As Spring continues to evolve, it’s capabilities become more and more attractive to use. Checkout this great article by David Parish on using Spring Boot with WebSphere!
Spring Boot is a wonderful tool for creating rich powerful applications with a limited amount of code or complexity. It can optionally include Spring Data with JPA support. The Spring abstraction layer for JPA makes creating database independent applications a snap. The problem is that it uses JPA 2.1 features which WebSphere 8.5.5 does not support.
WebSphere controls whether applications (EARs and WARs) are in PARENT_FIRST or PARENT_LAST classloading mode by its deployment.xml. RAD, or Rational Application Developer, has tools to generate this, as does the application server itself, but the Eclipse plugins do not at the time of this writing. So how do you configure your applications?
Wait, what does the classloading mode do?
Simply, when your application attempts to load a class, say IOUtils from Apache Commons IO, the JVM needs to know what to do when it finds multiple classes with the same fully qualified name. You could have classes provided by your application server, global JARs that you have put into your application server, and JARs in your application.
_PARENT_FIRST _classloading means take classes found in WebSphere (the parent), or global JARs first. So if you bundle a version of Apache Commons IO that doesn’t match the parent version, your application will run with the parent version instead of your application’s version.
_PARENTLAST classloading means prefer your application’s first.
So what’s the problem?
Imagine this scenario:
Your servers have global JARs setup that specific applications running in the same WebSphere profile require
You start a new application in your local development environment and you don’t realize the server has overridden certain JARs
You bundle newer versions of those JARs in your application So, with the “It works on my machine” stamp of approval you push to your servers only to find… failure.
There are plenty of other scenarios that could lead to an issue as well.
What’s the silver bullet?!
Unfortunately, there is no silver bullet. You may want to re-evaluate having shared libraries, update their versions, change the classloading mode of your application, or use a different WebSphere profile. The right answer really depends on your environment, but if changing the classloading mode is right for you, read on!
Changing the classloading mode
There are a few ways to make this change:
Deploy your application to WebSphere and update the configuration in the admin console (or wsadmin)
Use RAD (Rational Application Developer) to change it, if you have RAD
Primarily, the WebSphere version includes node/cell specifics. If you take that version and deploy to a different server, you will end up with new folders in your profile/installedApps directory. This doesn’t cause any issues (that I’ve experienced) but its annoying.
A better solution for non-RAD users
If you take a look at the RAD version, its pretty basic and just lists the applications deployed and which classloading mode they are in. The ids are a standard format with the time after them.
So, assuming you are not using anything else in deployment.xml, this file is easy to reproduce! And to make it easier, I created a command line application to do it for you!
jcl-over-slf4j-1.7.12.jar Additionally, I setup my application to use PARENT_LAST classloading. This is just something I have gotten used to, so if you have difficulties getting your code to work and you are not in PARENT_LAST, give that a try.
The servlet-context.xml has nothing special in it for this example, but the application-context.xml does. It points Spring to the WebSphere UOW Transaction Manager, and references the persistence unit to use:
Setting transaction-type to JTA (Java Transaction API)
Setting the JPA Provider to Hibernate
Setting the data source to our web component’s ExampleDb
Setting Hibernate to use the PostgreSQL dialect
Setting Hibernate to use the CMTTransactionFactory for container managed transactions
Setting Hibernate to use Webphere’s JTA Platform
And so on Note that I did have an issue with Hibernate on startup trying to determine type information, which is what hibernate.temp.use_jdbc_metadata_defaults resolved for me. I did not have to set this when using Oracle. This did not used to occur with older versions of Hibernate (e.g. 4.1.9.Final).
I have had success using Hibernate 4.1.9.Final using the same configuration, though I was using version 1.0 in my persistence.xml. Also, you must place the Hibernate JPA API 2.0 JAR that is included with Hibernate in the lib directory. If you migrate to WebSphere 8.5, you must remove that JAR.
Did you know you can run WebSphere Application Server in development mode, which optimizes it for less powerful hardware and for applications which see frequent updates? It’s actually quite easy, whether you are creating a new profile or working with an exciting one!
Creating a New Profile with the Profile Management Tool
If you are creating a new profile, via the Profile Management Tool (or PMT), just make sure you select these two boxes:
Use the “Advanced profile creation” mode This allows you to tweak some very simple settings that you may be interested in, I recommend all people using PMT to create their profiles in this mode.
Switch “Server runtime performance tuning setting” to “Development”
Then just finish the wizard with the settings you want!
Creating a New Profile via the Command Line manageprofiles Tool
For those command-line junkies like myself, creating a new profile via manageprofiles in development is also extremely easy. Simply add this flag to your -create parameter list:
That’s it! To read more about the parameters for manageprofiles, see here.
Modifying a Profile via the WebSphere Admin Console
If you’ve already created your profile, and want to simply enable development mode, simply log into the admin console and change it! It goes like this: