I am using a JMS client. The queue is a IBM MQ. When I write data on the queue, it is added with the RFH header. How can I strip the RFH header. I cannot use IBM MQ apis.
6 Answers
Another way is using the queue URI attributes (http://www.ibm.com/support/knowledgecenter/api/content/nl/en-us/SSFKSJ_7.5.0/com.ibm.mq.dev.doc/q032240_.htm#q032240___q032240_4).
The attribute targetClient
controls whether to use RFH or native format.
Queue queue = queueSession.createQueue("queue:///" + queueName + "?targetClient=1");
Using JNDI queue configuration you can set targetClient=MQ which has the same effect as targetClient=1:
<jmsQueue jndiName="jms/queue/name">
<properties.wmqJms CCSID="819" baseQueueName="MQ.QUEUE.NAME" encoding="273" targetClient="MQ"/>
</jmsQueue>
You can also set PROPCTL
to NONE
on the queue itself and that will strip the header, though in my experience it's best to do it with application configuration.
Starting from IBM WebSphere MQ v7, recommended way to tell the Java implementation NOT to generate MQRFH2 headers is to call MQDestination.setMessageBodyStyle( WMQConstants.WMQ_MESSAGE_BODY_MQ)
as TARGCLIENT
property is only used as a fallback option if MessageBodyStyle
was explicitly set to UNSPECIFIED
.
In your sender application call MQDestination.setTargetClient
method with WMQConstants.WMQ_CLIENT_NONJMS_MQ
as parameter. This will ensure RFH2
header is not included in the message.
The other value that can be used for setTargetClient method is MQJMS_CLIENT_JMS_COMPLIANT
. This indicates that the RFH2
format is used to send information. Applications that use WebSphere MQ classes for JMS understand the RFH2
format. Set the MQJMS_CLIENT_JMS_COMPLIANT
constant when you exchange information with a target WebSphere MQ classes for JMS application.
As some readers landing in this page CAN actually use IBM API, here's my code to publish messages for IBM MQ v8, for legacy clients that do not support RFH header.
package com.mycompany.mq.client;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Logger;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.JMSConsumer;
import javax.jms.JMSContext;
import javax.jms.JMSProducer;
import javax.jms.Queue;
import javax.jms.TextMessage;
import com.ibm.msg.client.jms.JmsConnectionFactory;
import com.ibm.msg.client.jms.JmsFactoryFactory;
import com.ibm.msg.client.wmq.WMQConstants;
import com.ibm.msg.client.wmq.compat.jms.internal.JMSC;
public class FileScanner {
private static final Logger logger = Logger.getLogger("RJEFileParser");
public final static char CR = (char) 0x0D;
public final static char LF = (char) 0x0A;
public final static String CRLF = "" + CR + LF; // "" forces conversion to string
public static void main(String[] args) throws Exception {
long m1,m2;
// Create a connection factory
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
JmsConnectionFactory cf = ff.createConnectionFactory();
// Set the properties
String sHost=Config.get("HOST");
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, sHost);
logger.info("WMQ_HOST_NAME:"+sHost);
String sPort=Config.get("PORT");
cf.setIntProperty(WMQConstants.WMQ_PORT, Integer.parseInt(sPort));
logger.info("WMQ_PORT:"+sPort);
String sChannel=Config.get("CHANNEL");
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, sChannel);
logger.info("WMQ_CHANNEL:"+sChannel);
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
String sQmgr=Config.get("QMGR");
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, sQmgr);
logger.info("WMQ_QUEUE_MANAGER:"+sQmgr);
String sAppName=Config.get("APPLICATION_NAME");
cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, sAppName);
logger.info("WMQ_APPLICATIONNAME:"+sAppName);
boolean bAuth = Boolean.parseBoolean(Config.get("AUTH")); // true
boolean bMqcsp = Boolean.parseBoolean(Config.get("USER_AUTHENTICATION_MQCSP")); // false
String sAppUser = null, sAppPass = null;
logger.info("Auth:"+bAuth);
if (bAuth) {
cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, bMqcsp);
logger.info("USER_AUTHENTICATION_MQCSP:"+bMqcsp);
if (!bMqcsp) {
sAppUser=Config.get("APP_USER");
cf.setStringProperty(WMQConstants.USERID, sAppUser);
logger.info("APP_USER:"+sAppUser);
sAppPass=Config.get("APP_PASSWORD");
cf.setStringProperty(WMQConstants.PASSWORD, sAppPass);
logger.info("APP_PASSWORD:"+sAppPass);
}
}
// Create JMS objects
try {
Connection con;
logger.info("Creating connection... context: \n"+ cf.toString());
if (bAuth && !bMqcsp) {
con = cf.createConnection(sAppUser, sAppPass);
}
else {
con = cf.createConnection();
}
con.close(); // connection was created for testing credentials and troubleshooting purposes
JMSContext context = cf.createContext();
//Set up the message
String text = "here goes your payload text" ;
logger.info("Text:"+text);
TextMessage message = context.createTextMessage(text);
// message.setIntProperty(WMQConstants.JMS_IBM_CHARACTER_SET , 437);
// message.setIntProperty(WMQConstants.JMS_IBM_ENCODING , 546);
message.setBooleanProperty(WMQConstants.WMQ_PERSISTENCE, Boolean.FALSE);
JMSProducer producer = context.createProducer();
// create Queue object
com.ibm.mq.jms.MQQueue q1 = new com.ibm.mq.jms.MQQueue();
q1.setBaseQueueManagerName("MYQUEUEMANAGERNAME");
q1.setBaseQueueName("MYINPUTQUEUENAME");
q1.setPersistence(DeliveryMode.NON_PERSISTENT);
q1.setTargetClient(JMSC.MQJMS_CLIENT_NONJMS_MQ); // Avoids RFH header!
// publish the message to queue
producer.send(q1, message);
logger.info("JMS message:\n" + message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Thanks for your replies. Answers from Stavr00 and Shashi was correct. Though I fixed it by using wmq resource adapter. In the configuration for the resource adapter, I used
<config-property name="targetClient">MQ</config-property>
This is equivalent to setting WMQConstants.WMQ_CLIENT_NONJMS_MQ to the queue.