You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JMS调用IBM MQ时主机返回2110 MQRC格式错误,请求代码校验

MQ转JMS代码后出现MQRC 2110格式错误的排查

问题描述

因IBM系统迁移,原使用的连接池管理器已不再受支持,我正在寻找替代的消息发送方案。现将原有MQ消息发送代码转换为JMS代码,但不确定转换格式是否正确,测试时主机端返回2110 MQRC FORMAT ERROR,请帮忙校验转换是否准确。

原有MQ代码

MQMessage reqMsg = new MQMessage();
reqMsg.messageId        = CMQC.MQMI_NONE;
reqMsg.correlationId    = CMQC.MQCI_NEW_SESSION;
reqMsg.userId           = racfUserid;
reqMsg.characterSet     = CHARSET_IBM500;

reqMsg.persistence      = persistence;
//  ---- create request message
String result = "";

byte blanks[] = new byte[8];
for (int i=0; i<blanks.length; i++)
   blanks[i] = (byte)' ';
reqMsg.clearMessage();
// ---- write MQCIH
reqMsg.writeString ("CIH ");              // MQCHAR4   StrucId;
reqMsg.writeInt (2);                      // MQLONG    Version;
reqMsg.writeInt (180);                    // MQLONG    StrucLength;
reqMsg.writeInt (reqMsg.encoding);        // MQLONG    Encoding;
MQPutMessageOptions pmo = new MQPutMessageOptions();
pmo.options = CMQC.MQPMO_NEW_MSG_ID |
                             CMQC.MQPMO_SET_IDENTITY_CONTEXT |
                             CMQC.MQPMO_FAIL_IF_QUIESCING;
requestQueue.put (reqMsg, pmo);

转换后的JMS代码

Hashtable<String, String> environment = new Hashtable<String, String>();

environment.put(Context.INITIAL_CONTEXT_FACTORY,
    "com.ibm.websphere.naming.WsnInitialContextFactory");

Context context = new InitialContext(environment);

ConnectionFactory connectionFactory = (ConnectionFactory) context
    .lookup("name");

Destination requestQueue = (Destination) context
    .lookup(requestQueueName);
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(false,
    Session.AUTO_ACKNOWLEDGE);
Destination replyQueue = (Destination) context
    .lookup(replyToQueueName);
context.close();
MessageProducer producer = session.createProducer(requestQueue);


BytesMessage message = session.createBytesMessage();

message.setJMSMessageID(MQConstants.MQMI_NONE.toString());
message.setJMSCorrelationIDAsBytes(MQConstants.MQCI_NEW_SESSION);
message.setJMSReplyTo(replyQueue);
message.setStringProperty("JMS_IBM_MQMD_UserIdentifier", racfUserid);
message.setIntProperty("JMS_IBM_MQMD_CodedCharSetId",

byte blanks[] = new byte[8];
for (int i = 0; i < blanks.length; i++)
  blanks[i] = (byte) ' ';

// Construct the CIH header as a byte array
ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
DataOutputStream outData = new DataOutputStream(outBytes);

outData.writeBytes("CIH "); // MQCHAR strucId
outData.writeInt(2); // MQLONG version
outData.writeInt(180); // MQLONG strucLength
outData.writeInt(messageEncoding); // MQLONG encoding
outData.writeInt(CHARSET_IBM500); // MQLONG CodedCharSetId;


StringBuffer pgmName = new StringBuffer(progName);
for (int i = pgmName.length(); i < 8; i++)
  pgmName.append(' ');

outData.writeBytes(pgmName.substring(0, 8)); 
outData.writeBytes(commArea);

byte[] cihRequestMessage = outBytes.toByteArray();
message.writeBytes(cihRequestMessage);
producer.send(message);

MessageConsumer consumer = session.createConsumer(replyQueue);

Message replyMessage = consumer.receive(replyTimeout * 1000);

问题排查与修正建议

以下是转换代码中存在的几个关键问题,这些可能是导致2110 MQRC FORMAT ERROR的原因:

1. 未完成的代码行

JMS代码中这一行未完成,缺少属性值:

message.setIntProperty("JMS_IBM_MQMD_CodedCharSetId",

需补充为:

message.setIntProperty("JMS_IBM_MQMD_CodedCharSetId", CHARSET_IBM500);

2. CIH结构长度不匹配

原MQ代码中设置CIH的StrucLength为180字节,但JMS代码中额外写入了CodedCharSetId、程序名(pgmName)和commArea,导致实际生成的CIH结构长度远超180字节。主机端会校验结构长度,不匹配就会触发格式错误。

需严格按照原MQ代码的CIH写入逻辑,仅写入原代码中的四个字段:StrucId、Version、StrucLength、Encoding,不要额外添加其他字段。

3. 消息ID设置错误

原MQ代码中reqMsg.messageId = CMQC.MQMI_NONE是让MQ自动生成新消息ID,对应JMS中不需要手动设置JMSMessageID(默认由系统生成)。当前代码中用字符串设置的方式错误,应改为字节数组方式,或者直接省略(因为MQPMO_NEW_MSG_ID对应JMS默认行为):

// 错误写法
message.setJMSMessageID(MQConstants.MQMI_NONE.toString());
// 正确写法(可选,实际可省略)
message.setJMSMessageIDAsBytes(MQConstants.MQMI_NONE);

4. 缺失持久化设置

原MQ代码设置了reqMsg.persistence = persistence,但JMS代码中未对应设置消息的持久化模式,需补充:

int jmsDeliveryMode = (persistence == CMQC.MQPER_PERSISTENT) ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT;
message.setJMSDeliveryMode(jmsDeliveryMode);

5. 身份上下文未设置

原MQ代码中PMO包含CMQC.MQPMO_SET_IDENTITY_CONTEXT选项,该选项会将消息的身份上下文设置为当前用户,JMS中需对应设置属性:

message.setStringProperty("JMS_IBM_MQMD_IdentityContext", racfUserid);

6. 编码值一致性问题

原MQ代码中使用reqMsg.encoding(MQ消息的默认编码),JMS代码中的messageEncoding需确保与原代码的reqMsg.encoding值一致,建议直接使用CMQC.MQENC_NATIVE或原代码对应的编码常量。

内容的提问来源于stack exchange,提问作者Sheela

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 02:59:57