Thursday, April 30, 2009

Mule: Sending a JMS Message to WebSphere MQ

The Mule Client documentation example for sending a JMS message to a JMS queue seems simple enough:
    MuleClient client = new MuleClient();
client.dispatch("jms://my.queue", "Message Payload" null);
I was having trouble sending a JMS message to endpoint hooked to the following WebSphere MQ connector. The connector has a JMS to Object transformer for the incoming message. Sending a String as in the example produced an execption related to the connection factory stating that the incoming object was of type Class and not a JMS message. The connector:
  <jms:connector name="jmsConnectorWMQ"
connectionFactory-ref="WMQConnectionFactory"
maxRedelivery="5"
specification="1.1"
persistentDelivery="true"
numberOfConcurrentTransactedReceivers="5">
<service-overrides inboundTransformer="Jms2Obj"/>
</jms:connector>

<jms:jmsmessage-to-object-transformer name="Jms2Obj"/>
The connection factory:
  <spring:bean name="WMQConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<spring:property name="transportType" value="1"/>
<spring:property name="hostName" value="${jms.connection.hostname}"/>
<spring:property name="port" value="${jms.connection.port}"/>
<spring:property name="queueManager" value="${jms.queue.manager}"/>
<spring:property name="channel" value="${jms.connection.channel}"/>
</spring:bean>

I was able to create and send a JMS message with the following method. Without giving the ObjectToJMSMessage transformer an endpoint, an exception was thrown stating the transformer requires a javax.jms.Session. The String to send is transformed to a JMS message to make the connector happy.

The URL returned by the getUrl() method below was the address of a JMS queue, for example: jms://request.queue. Im using MuleClient.send() because I want the response returned synchronously.

The method:

protected String sendRequest(Object request) throws Exception {

EndpointFactory endpointFactory = new DefaultEndpointFactory();
MuleContext context = MuleServer.getMuleContext();
endpointFactory.setMuleContext(context);
ImmutableEndpoint endpoint = endpointFactory.getInboundEndpoint(getUrl());

ObjectToJMSMessage transformer = new ObjectToJMSMessage();
transformer.setEndpoint(endpoint);

Object transformedMessage = transformer.doTransform(request, "UTF-8");

MuleClient client = new MuleClient();
MuleMessage responseMessage = client.send(getUrl(), transformedMessage, null);
String response = responseMessage.getPayloadAsString(ENCODING);

return response;
}

This seems like a lot of work to me to send a simple JMS message to WebSphere MQ, but it works. A suggestions for alternative would be greatly appreciated.

A better approach: I left this as a comment but it doesn't display too nicely...

With com.ibm.mqjms.jar, sending the JMS message is much easier. I wish I would of found this earlier.

With the following imports:
    import com.ibm.jms.JMSTextMessage;
import com.ibm.mq.jms.MQJMSStringResources;
The original method is greatly simplified to:
    protected String sendRequest(Object request) throws Exception {

MQJMSStringResources resources = new MQJMSStringResources();
JMSTextMessage jmsMessage = new JMSTextMessage(resources, (String)request);
jmsMessage.setText((String)request);

MuleClient client = new MuleClient();
MuleMessage responseMessage = client.send(getUrl(), jmsMessage, null);

String response = responseMessage.getPayloadAsString(ENCODING);

return response;
}

10 comments:

  1. Using the com.ibm.mqjms.jar directly is easier but you just made your made code dependent on the IBM implementation. You should always code to interfaces (i.e. JMS) rather than specific implementations. This will make your code portable between JMS implementations.

    ReplyDelete
  2. WebSphere MQ, a member of the WebSphere family from IBM, was the most popular system for messaging across multiple platforms.
    .your providing good mater .
    IBM MQ SERIES ADMIN ONLINE TRAINING


    ReplyDelete
  3. Hi,

    Thanks this is helping.

    I have little different requirement. Please let me know, if you can help...

    I need to create a flow to read/receive messages from WMQ - Queue and within my flow, i need to access WMQ Message Header values (like MQMD.ApplIdentityData and other properties).

    any help would be highly appreciated.

    ReplyDelete
  4. Thank you for sharing wonderful information with us to get some idea about MuleSoft. check it once through
    Mulesoft Online Training

    ReplyDelete
  5. Thanks for shearing good information...Mulesoft ESB Training in HyderabadBest Mulesoft Training institutes in Hyderabad Mulesoft Training realtime trainers in Hyderabad, Mulesoft Training course fee in Hyderabad, Mulesoft Training course details, online Mulesoft Training institutes in Hyderabad, online Mulesoft Training courses in Hyderabad, Mulesoft Training centers in Hyderabad, learn Mulesoft Training , Mulesoft Training videos, Mulesoft Training materials, Mulesoft Training study materials, Mulesoft Training corporate trainers in Hyderabad, best Mulesoft Training classes in Hyderabad online Mulesoft Training classes in Hyderabad, top Mulesoft Training institutes in Pune, leading Mulesoft Training institutes in Hyderabad, Mulesoft Training course contents, Mulesoft Training course structure, online Mulesoft Training

    ReplyDelete

  6. IT's very informative blog and useful article thank you for sharing with us , keep posting learn more

    Informatica Training

    ReplyDelete
  7. I am reading your post from the beginning, it was so interesting to read & I feel thanks to you for posting such a good blog, keep updates regularly.I want to share about Mulesoft training in hyderabad .

    ReplyDelete
  8. Thank you so much for your excellent blog! I really enjoy to visit your very interesting post, Well done!
    Best Family Lawyer for Dads
    Child Support Virginia

    ReplyDelete