Monday, March 16, 2015

JMS testing with HermesJMS

HermesJMS is a handy tool that can be used to visually interact with JMS destinations (JMS Queues or JMS Topics).  I find it convenient for ad hoc testing of JMS applications.  I use it to monitor the status of JMS Queues, browse their contents, and to drop messages onto queues for testing purposes.  

When viewing a message in a JMS Queue, HermesJMS shows you the JMS headers and the value of the message payload, even if the payload is a serialization of a custom Java object.   For example, in my current consulting engagement, we had a situation where we had a bad message stuck at the front of one of our JMS Queues (and due to invalid configuration our app kept processing that same message over and over, rather than proceeding onto the next message in the queue).  Through the WebLogic Console we were able to see that there was a message in the queue that wasn't getting processed, but we couldn't see the actual content of the message that was causing it to get stuck.  By connecting HermesJMS to the queue we could view the message payload and as a result identify and fix the issue.

Browse Queue Contents

The screenshot below shows an example of what browsing messages in a JMS Queue looks like:


The table lists the JMS messages currently in the queue and the JMS headers for each message.  Below the table is then a text rendering of the actual payload (typically a serialized Java object).  In this example the payload is a Java class called HermesDemo with two properties, foo and bar (which I creatively concocted for this blog post :)

Drag Messages Between Queues

Another handy feature of HermesJMS is that you can easily copy messages between queues.  For example, if I click on the top message in the demo/Queue on my local machine I can drag it over to a queue in my testing environment (UAT):


HermesJMS asks me to confirm the action and then copies the message over.  HermesJMS will automatically handle any necessary mapping if the JMS Destination names differ between the source and the target queues.  I find this drag and drop feature quite handy for ad hoc testing JMS applications in multiple environments.  I produce a message on one of my local queues and then drag it as needed onto a corresponding queue in the environment I want to test.  

Build Message Stores

HermesJMS also has a feature where you can build so called stores; that work off of a database rather than an actual JMS destination.  Using this feature you can build a database of various JMS messages and have them ready for dragging over to a remote destination anytime you need to test a specific condition in one of your JMS applications.

XML Export/Import

Alternatively HermesJMS allows you to export messages to XML files, for later import into queues/topics. To do this, you simply click on a message in the queue and select Save as XML... from the Messages menu, then give it a file name and hit save.  To import the message to a queue you click on the JMS Queue and select Send XML Encoded Messages from the Messages menu and then select the XML file to import from on your hard drive:


Note: if the JMS Destination name does not match between the source and target queues you will need to edit the XML and update the value to match that of the target queue.  

In our example the exported DemoClass.xml file looks like this:

where the value of the object tag is an object serialization + Base64 encoding of the following Java class:

When you export a message from a Queue to XML, HermesJMS handles the serialization magic for you and writes it out to the XML file.   If you want to create a new XML message from scratch (e.g. when adding the first message for a queue), you can build the serialization string using the SerializeHermesDemoClass in my Github repo (just modify the main method to use whatever class you want to serialize).

Setup Instructions

Below are basic instructions for getting HermesJMS set up.  In my case I am using WebLogic as the application server.  Setup for other app servers is similar; you just need to use the ContextFactory and jar files specific to that app server.  If you go to hermesjms.com you will find setup instructions for many app servers under the Providers menu.

  1. Download and install HermesJMS, either directly from Sourceforge or as part of SoapUI install.
  2. Start HermesJMS by running hermes.bat/hermes.sh.
  3. Create a ClasspathGroup for your app server jar files 
    1. Select Option and Preferences
    2. Click on the Providers tab
    3. Right-click on Classpath Groups and select Add Group and give it a name (e.g. JarDependencies)
    4. Click the + sign and right-click on Library and select Add Jars and find the jar files you want to import.  In our case that is weblogic.jar, wlclient.jar, and HermesDemo.jar, which has the custom Java class used in our demo.  If you want HermesJMS to show the contents of a custom Java object in your JMS Queue, it needs to have the corresponding class file on its classpath.  You can either add the jar here, or alternatively edit hermes.bat/hermes.sh and add it where the CLASSPATH variable gets set.
  4. Next we need to create a Session for JNDI browsing the JMS server 
    1. On the Preferences screen, click the Sessions tab.
    2. Give the session a name, corresponding to the JMS server you are pointing it to.
    3. Select the Plug In matching your app server.  In our case it is BEA WebLogic.
    4. Under Loader, select your JarDependencies and under Class select hermes.JNDIConnectionFactory.
    5. Populate the binding, initialContextFactory, providerUrl, and security properties as appropriate for your app server.  For WebLogic the properties are:
    6. If the destination names don't get auto-populated, right-click under Destinations and add the names of JMS Queues/Topics you want to connect to on the JMS Server.

Note: If you are using WebLogic you can alternatively download this
pre-populated hermes-config.xml file and put it in your .hermes directory (replacing the default one that HermesJMS puts there during install).  Before you run HermesJMS make sure you edit the file and change the following:
  • Update the providerUrl value to match the server and port of your JMS Server.
  • Set the securityCredentials and securityPrincipal values to mach your username and password.
  • Edit the library paths for JarDepdencies and make sure they point to wherever you have these jar files on your machine.

In Conclusion

I hope this overview and these setup instructions help you get going with HermesJMS.  Once you have it working, interacting with your JMS destinations is a breeze, and testing a given JMS app can be as simple as a drag and drop.

If you need to run a suite of JMS tests, e.g. for sanity testing or load testing, you can use SoapUI, which knows how to interact with HermesJMS.  I may write a future blog post demonstrating this integration.  For SoapUI basics, see this blog post.

All the examples used for this blog post can be seen in this Github repo.

Happy JMSing!

6 comments:

shiva vuppala said...

Hi Steinn Jonsson,

As mentioned did you write a blog to use SoapUI in pooling messages using HermesJMS.
If so can you please share the info. It is very much important for me at this point in time.

Thanks

Steinn Jónsson said...

No, I haven't gotten around to it. Will let you know if I do.

Jayne Hamilton said...

Really nice article on setup and possibilities of the tool.
Just in case anyone has problems setting up Hermes for a remote glassfish server using OpenJMS and get the following error message:

hermes.HermesException: The default provider extension cannot discover queues or topics on hermes.ext.imq.ConnectionFactory
at hermes.ext.HermesAdminSupport.discoverDestinationConfigs(HermesAdminSupport.java:449)

remember to setup the SunMQ plugin in the Plugin options at the top of the Preferences.
We also had to download Hermes JMS in addition to SOAP UI in order to add the hermes-imq.jar to the classpath group. Otherwise, there was no hermes.ext.imq.ConnectionFactory available with corresponding properties for remote access to OpenJMS on Glassfish.

Steinn Jónsson said...

Jayne, thanks for the tip

locker said...

I like your thoughts due to your skills.

Anonymous said...

The hyperlink to HermesJMS in the top [http://www.hermesjms.com/] ends up going to https://www.edmunds.com/?utm_medium=sem&utm_source=admarketplace&utm_account=edmunds&utm_campaign=sem_adm_ron&utm_adgroup=utm-migration&utm_term=ron_new_092016&utm_content=c1530805744020200025

is this an intentional redirect of the traffic for $ or is there a bug in the address? I'm pretty sure HermesJMS isn't the same as Edmunds Cars ;)