导致异常的 IBM 字符集标头

Posted

技术标签:

【中文标题】导致异常的 IBM 字符集标头【英文标题】:IBM Character Set Header Causing Exceptions 【发布时间】:2016-07-21 11:35:18 【问题描述】:

我们有一个 Spring Integration 流,它使用 Websphere MQ 管理器队列中的消息。这些消息经过一个简单的过程,然后被放入另一个队列(在同一个 MQ 管理器中)。

当我们尝试将消息写入最终目标队列时,我们收到以下错误:

Caused by: javax.jms.JMSException: MQJMS1006: invalid value for 'JMS_IBM_Character_Set': 'IBM850'.
        at com.ibm.msg.client.wmq.v6.jms.internal.ConfigEnvironment.newException(ConfigEnvironment.java:431) ~[com.ibm.mqjms-7.0.1.3.jar:7.0.1.3 - k701-103-100812]
        at com.ibm.msg.client.wmq.v6.jms.internal.MQMessageProducer.sendInternal(MQMessageProducer.java:1153) ~[com.ibm.mqjms-7.0.1.3.jar:7.0.1.3 - k701-103-100812]
        at com.ibm.msg.client.wmq.v6.jms.internal.MQMessageProducer.send(MQMessageProducer.java:779) ~[com.ibm.mqjms-7.0.1.3.jar:7.0.1.3 - k701-103-100812]
        at com.ibm.msg.client.wmq.v6.jms.internal.MQMessageProducer.send(MQMessageProducer.java:2718) ~[com.ibm.mqjms-7.0.1.3.jar:7.0.1.3 - k701-103-100812]
        at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.sendMessage(JmsMessageProducerImpl.java:907) ~[com.ibm.mqjms-7.0.1.3.jar:7.0.1.3 - k701-103-100812]
        at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.send_(JmsMessageProducerImpl.java:762) ~[com.ibm.mqjms-7.0.1.3.jar:7.0.1.3 - k701-103-100812]
        at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.send(JmsMessageProducerImpl.java:393) ~[com.ibm.mqjms-7.0.1.3.jar:7.0.1.3 - k701-103-100812]
        at com.ibm.mq.jms.MQMessageProducer.send(MQMessageProducer.java:333) ~[com.ibm.mqjms-7.0.1.3.jar:7.0.1.3 - k701-103-100812]
        at org.springframework.jms.connection.CachedMessageProducer.send(CachedMessageProducer.java:181) ~[spring-jms-4.2.1.RELEASE.jar:4.2.1.RELEASE]
        at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:636) ~[spring-jms-4.2.1.RELEASE.jar:4.2.1.RELEASE]
        at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:607) ~[spring-jms-4.2.1.RELEASE.jar:4.2.1.RELEASE]
        at org.springframework.jms.core.JmsTemplate$4.doInJms(JmsTemplate.java:584) ~[spring-jms-4.2.1.RELEASE.jar:4.2.1.RELEASE]
        at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:494) ~[spring-jms-4.2.1.RELEASE.jar:4.2.1.RELEASE]
        at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:580) ~[spring-jms-4.2.1.RELEASE.jar:4.2.1.RELEASE]
        at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:706) ~[spring-jms-4.2.1.RELEASE.jar:4.2.1.RELEASE]
        at org.springframework.integration.jms.JmsSendingMessageHandler.send(JmsSendingMessageHandler.java:145) ~[spring-integration-jms-4.2.0.RELEASE.jar:?]
        at org.springframework.integration.jms.JmsSendingMessageHandler.handleMessageInternal(JmsSendingMessageHandler.java:115) ~[spring-integration-jms-4.2.0.RELEASE.jar:?]
        at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127) ~[spring-integration-core-4.2.0.RELEASE.jar:?]

我们从初始队列中提取的消息具有以下 IBM 特定的标头:

JMS_IBM_Character_Set=IBM850,
JMS_IBM_MQMD_CodedCharSetId=850,
JMS_IBM_Encoding=17,
JMS_IBM_PutApplType=11,
JMS_IBM_Format=        ,
JMSXDeliveryCount=1,
JMS_IBM_PutTime=12534150,
JMS_IBM_MsgType=8

当我们尝试将处理后的消息写入最终的 Websphere MQ 队列时,它们仍然存在。

该项目正在使用以下 IBM MQ 依赖项 jar:

compile 'com.ibm:com.ibm.mq:7.0.1.3'
compile 'com.ibm:com.ibm.mqjms:7.0.1.3'
compile 'com.ibm:com.ibm.mq.jmqi:7.0.1.3'
compile 'com.ibm:com.ibm.mq.headers:7.0.1.3'

解决此异常的正确方法是什么?我们应该:

    在写入之前从邮件中去除任何JMS_IBM_XXX 标头 到最终的 Websphere MQ 队列? 使用不同版本的 jar? 完全做其他事情?

在从 Websphere MQ 队列获取消息并最终将它们写入另一个 Websphere MQ 队列的任何其他流中,我们似乎没有遇到此问题。

【问题讨论】:

【参考方案1】:

引用WebSphere MQ 7.5 - MS_IBM_Character_Set:

在 WebSphere® MQ V7.5 之前,使用 WebSphere MQ 消息传递提供程序迁移模式的应用程序可以将消息的 JMS_IBM_Character_Set 属性设置为数字编码字符集标识符。

发送消息时,存储在 JMS_IBM_Character_Set 属性中的编码字符集标识符被映射到 MQMD 字段 CodedCharacterSetID。

当为 JMS 使用 WebSphere MQ V7.5 类时,包含以下消息的 JMSException:

MQJMS1006: invalid value for 'JMS_IBM_Character_Set': '<number>'

如果应用程序尝试发送将 JMS_IBM_Character_Set 属性设置为数字编码字符集标识符的消息。

JMS_IBM_Character_Set 属性必须设置为映射到应用程序要使用的编码字符集标识符的 Java 字符集字符串。欲了解更多信息,请参阅Mapping JMS fields onto WebSphere MQ fields (outgoing messages)

由于您使用的是 7.0.1.3 版本,而不是 7.5 或更高版本,因此该值必须是 "numerical Coded Character Set Identifier",这意味着它应该是 850(数字),而不是 @987654326 @。

在 7.5 版中应该是IBM850

【讨论】:

将 IBM MQ 依赖 jar 更新到 7.5 解决了这个问题。

以上是关于导致异常的 IBM 字符集标头的主要内容,如果未能解决你的问题,请参考以下文章

像这样更改字符串的内容是不是会导致异常?

Windows字符编码集大全

特殊字符u2028导致的Javascript脚本异常

Java反射机制清空字符串导致业务异常分析

xml 特殊字符 导致的 solr 数据导入异常

为啥创建静态 const std::string 会导致异常?