I have been banging my head against the wall this week over weird things in WMQ v7, so I figured I would post this so that people in the future would have less of a headache.
A year or so ago, I noticed some odd behavior in WMQ v7 with Java applications reading messages with a message format of MQRFH2 but I ignored it because I was simply far to busy to investigate it.
This week I decided to do so testing of Java applications using WMQ v7.0 and Java JMS applications using WMQ v7.1. Nothing too strange about that. If the Java application put JMS (MQRFH2) messages on the queue then the Java JMS application was able to consume them (normal stuff). When the Java JMS application put JMS (MQRFH2) messages on the queue, the Java application would throw an exception because it was receiving a message with MQMD.Format set to MQSTR. When I looked at the message via MQ Explorer or MQ Visual Edit, there it was in the queue as a plain message and no MQRFH2 but rather MQSTR for the message format.
At first, I thought I messed up my bindings file. I checked and checked, and the JMS queue property ‘TARGCLIENT’ was set to ‘JMS’.
When I would run a JMS application, it could consume the message without any issue. Hence, the head banging had begun. Plus if I ran the exact same Java application but with the WMQ v6 MQ JAR files, everything was fine.
I did testing of messages with a format of MQRFH v1, MQCIH, MQDEAD, MQIIH, MQXMIT, MQHSAP and SMQBAD and all of these messages worked as expected in WMQ v6, WMQ v7.0 and WMQ v7.1. It was as if I had a virus on my server but only for WMQ v7.0 and WMQ v7.1 queue managers.
The other weird item that I noticed, is that the length of the message, as shown by MQ Explorer or MQ Visual Edit was wrong for the data it was presenting. The length value included the missing/non-existent MQRFH2 header plus the message data.
I tried hundreds of combinations, searched the internet (read the manuals) and came up with nothing. Today, just by dumb luck, I stumped across a small paragraph in the WMQ Using Java manual and it said:
Existing applications which rely on the presence of MQRFH2s containing properties must be changed to use the get*Property methods or to specify MQC.MQGMO_PROPERTIES_FORCE_MQRFH2 to continue receiving properties in the MQRFH2 format. If the application cannot be changed then the queue attribute PropertyControl can be changed to the value MQPROP_FORCE_MQRFH2 so that properties are always returned in MQRFH2 form.
Are you kidding me!!! Who at IBM thought it was a good idea to change the default behavior of the processing of 1 message type? But not change the behavior for the others: MQRFH v1, MQCIH, MQDEAD, MQIIH, MQXMIT, MQHSAP and SMQBAD. There are millions of Java (non-J2EE) applications running in the real world that expect and deal with MQ messages with a format of MQRFH2.
Who ever came up with this bright idea (sarcasm) should be demoted or fired. This is so customer unfriendly that it boggles the mind. WMQ v6 goes out of support in 7 months (September 2012). There will be thousands/millions of queue managers upgraded in the coming months and there will be millions of deployed Java (non-J2EE) applications that will instantly break for no fault of any developer or support person. And in this case, developers will be correct in saying that it is MQ’s fault that their application no longer works!
I am just floored at the stupidity in this decision. IBM could have added the feature but made it optional. i.e. Java applications receive the messages with the format MQRFH2 as it was in WMQ v5.3 and WMQ v6.0.
Secondly, why implement the feature for only 1 message type? What about messages with the format of MQRFH v1, MQCIH, MQDEAD, MQIIH, MQXMIT, MQHSAP and SMQBAD? Why wasn’t this abstraction available for those message types?
Third, why did IBM only implement the abstract layer for Java (non-J2EE)? What is wrong with native applications? There are millions of native (C/COBOL) applications that deal with MQRFH2 messages but IBM decided that they do not qualify for this nice new feature? What, is IBM giving the middle-finger to native applications? (A lot of that going on lately).
Fourth, who implements an abstraction layer but sets the message length to the wrong value. If the abstraction layer is pulling the message data out of the MQRFH2 message and changing the MQMD.Format field to MQSTR then it bloody well better set the message data length to the correct length.
Everybody keeps talking about the 2012 Apocalypse, well, way to go IBM. You have just created your own 2012 Apocalypse with this goofy and strangely implemented Java (only) abstraction layer.
Do you have ANY idea of how many Java applications that have been running untouched for 5+ years? With all the merges and layoffs of the last 10 years, do you have ANY idea of how many production Java applications where the source code is lost?
I hope IBM support staff is ready for the number of PMRs that people will open over this issue. How many thousands of hours will be lost by customer’s support staff and MQAdmins trying to figure out why things are crashing?
After the customer has wasted numerous hours of support staff time and opened a PMR with IBM, IBM will say, change your application code or change the queue’s PropertyControl attribute to “Force MQRFH2”.
As I said, are you kidding me.
To all of those MQ customers that are or who will be feeling this pain, you have my sympathy and hopefully this blog posting helps you out.