Suppress MQJE001 in System.err log output when an MQException occurs

When you use WebSphere MQ API for Java, exceptions in MQ layer result in a short message logged to System.err, looking like this:

MQJE001: Completion Code 2, Reason 2033

It may be quite annoying because this happens before you have a chance to catch MQException. This is especially unfortunate if the exception does not represent a true error condition in your program. This particular reason code 2033, stands for MQRC_NO_MSG_AVAILABLE and is returned when a get call with options does not find a suitable message. This may be a perfectly normal situation, e.g. for a message poller program. Is it possible to suppress this output?

Yes, it is possible, but it can only be done for one reason code at a time using static method logExclude on MQException class:

MQException.logExclude(MQException.MQRC_NO_MSG_AVAILABLE);

Identify service requestor application for MQ and Web services

Suppose you are establishing SOA in an organization that is quite new to the concept. They have a developed MQ infrastructure and are quickly building up enterprise Web Services catalog. A lot of existing functionality and legacy applications will be exposed as Web Services and MQ. You must continue to support MQ services because there is still a large number of MQ clients there that can not be reasonably changed. But enterprise architects want to gain better control of the enterprise services, including both Web Services and MQ. They want to establish service governance. All service consumers will be required to subscribe to the services they need and establish an SLA. To enforce this policy, Enterprise Service Bus in the middle of SOA landscape will need to authenticate requester and verify SLA. Authentication needs to be done on application level, not individual user level, because SLA is established for departments/LOBs and not for users.

What is the easiest way to find out which application sent an MQ request message? Consider this constraint: source applications can not be modified to insert their identity into the message. First, I will assume that I can differentiate applications by Queue Manager: each QM from which request messages may be sent will represent only one application. This is already the case, but even it was not, we could create additional QMs as required and reconfigure some applications to use new QMs. With this assumption, my problem has been reduced to identifying Queue Manager that sent each message. After that I can use a table to map QM name to application name. This can be done in several ways. It can be done quite elegantly by WebSphere Message Broker. It can be done by MQ means alone, in a way that is both cute and ugly at the same time:

  • create a user account for each source QM
  • on a “central” QM, create a queue for each source Queue Manager
  • limit PUT on each of these queues to a single user corresponding to its QM
  • configure MCAUSER on channels

With some trimming around the edges, I can guarantee that messages on each of these queues have arrived from a single QM.

This is quite a bit of work. I can achieve a rough first cut of a solution much easier. I will add an assumption that only request-response pattern is used (no datagrams, all request messages require a response). Now I can identify service requester by finding where the reply message goes. That’s right: ReplyToQMgr property of MQMD structure carries the name of Queue Manager that expects a response. Under normal circumstances, by looking at this property we can identify which QM sent the message because it is the same QM that the response will be sent to. All that’s left is control for spoofed messages, which is an open item as of now.