我写了一个客户端来读取通过MQ发送的分段消息,但收到错误消息。下面的代码工作完全正常,但它在时间读取单个消息,应用程序必须连接分段的消息,这不是我想要的
public void getMessage(){
try {
MQEnvironment.hostname = "";
MQEnvironment.channel = "";
MQEnvironment.port = ;
MQQueueManager QMgr = new MQQueueManager("MQManager");
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQConstants.MQOO_INPUT_AS_Q_DEF|
MQConstants.MQGMO_WAIT|
MQConstants.MQGMO_ALL_SEGMENTS_AVAILABLE|
MQConstants.MQGMO_LOGICAL_ORDER;
gmo.matchOptions = MQConstants.MQMO_NONE;
gmo.waitInterval = MQConstants.MQWI_UNLIMITED;
MQMessage message = new MQMessage();
MQQueue queue = QMgr.accessQueue("QName",
gmo.options);
while(true){
queue.get(message, gmo);
int dataLength = message.getDataLength();
System.out.println(message.readStringOfCharLength(dataLength));
message.clearMessage();
}
} catch (Exception e) {
e.printStackTrace();
}
}
当我将MQGMO_SYNCPOINT添加到选项时,它会因com.ibm.mq.MQException而失败:MQJE001:完成代码' 2',原因' 2046'。
不确定为什么会失败,如果我能够至少让它工作,我将能够在安全处理应用程序中的所有分段消息后提交。
public void getMessage(){
try {
MQEnvironment.hostname = "";
MQEnvironment.channel = "";
MQEnvironment.port = ;
MQQueueManager QMgr = new MQQueueManager("MQManager");
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQConstants.MQOO_INPUT_AS_Q_DEF|
MQConstants.MQGMO_WAIT|
MQConstants.MQGMO_ALL_SEGMENTS_AVAILABLE|
MQConstants.MQGMO_LOGICAL_ORDER|
MQConstants.MQGMO_SYNCPOINT;
gmo.matchOptions = MQConstants.MQMO_NONE;
gmo.waitInterval = MQConstants.MQWI_UNLIMITED;
MQMessage message = new MQMessage();
MQQueue queue = QMgr.accessQueue("QName",
gmo.options);
while(true){
queue.get(message, gmo);
int dataLength = message.getDataLength();
System.out.println(message.readStringOfCharLength(dataLength));
QMgr.commit();
message.clearMessage();
}
} catch (Exception e) {
e.printStackTrace();
}
}
当我尝试将分段消息作为单个消息读取时;它失败了 com.ibm.mq.MQException:MQJE001:完成代码' 2',Reason' 2046'。
如果有人能帮助解决这个问题,我将不胜感激;我不确定下面的代码有什么问题。这是我阅读分段消息的首选方式。
public void getMessage(){
try {
MQEnvironment.hostname = "";
MQEnvironment.channel = "";
MQEnvironment.port = ;
MQQueueManager QMgr = new MQQueueManager("MQManager");
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQConstants.MQOO_INPUT_AS_Q_DEF|
MQConstants.MQGMO_WAIT|
MQConstants.MQGMO_COMPLETE_MSG;
gmo.matchOptions = MQConstants.MQMO_NONE;
gmo.waitInterval = MQConstants.MQWI_UNLIMITED;
MQMessage message = new MQMessage();
MQQueue queue = QMgr.accessQueue("QName",
gmo.options);
while(true){
queue.get(message, gmo);
int dataLength = message.getDataLength();
System.out.println(message.readStringOfCharLength(dataLength));
message.clearMessage();
}
} catch (Exception e) {
e.printStackTrace();
}
}
答案 0 :(得分:2)
问题在于您使用gmo.options
作为accessQueue
方法的开放选项和get
的获取消息选项。您正在混合两个打开选项并在此字段中获取消息选项。
每个选项都由选项字段中的一个位表示。当您将该字段用作打开选项时,即使您指定了get message选项,MQ也会将这些位解释为打开选项,相反,当您使用该字段作为获取消息选项时,它们将被MQ解释为获取消息选项。 / p>
让我们看一下您在样本中指定的每个选项的值,以及基于值的等效open或get选项:
MQOO_INPUT_AS_Q_DEF 0x00000001
MQGMO_WAIT 0x00000001
MQOO_INPUT_SHARED 0x00000002
MQGMO_SYNCPOINT 0x00000002
MQOO_RESOLVE_NAMES 0x00010000
MQGMO_COMPLETE_MSG 0x00010000
MQOO_BIND_NOT_FIXED 0x00008000
MQGMO_LOGICAL_ORDER 0x00008000
MQOO_RESOLVE_LOCAL_Q 0x00040000
MQOO_RESOLVE_LOCAL_TOPIC 0x00040000
MQGMO_ALL_SEGMENTS_AVAILABLE 0x00040000
由于您错误地将其用作QMgr.accessQueue("QName",
gmo.options
);
的开放选项,因此MQ会以意想不到的方式解释此问题。
为您的第一个"工作"例如,开放选项将被解释为如下所示,这些特定的开放选项一起不会对本地队列造成任何问题,这就是为什么它是"工作"即使它不正确:
MQOO_INPUT_AS_Q_DEF 0x00000001
MQOO_INPUT_AS_Q_DEF 0x00000001 //MQGMO_WAIT
MQOO_RESOLVE_LOCAL_Q 0x00040000 //MQGMO_ALL_SEGMENTS_AVAILABLE
MQOO_RESOLVE_LOCAL_TOPIC 0x00040000 //MQGMO_ALL_SEGMENTS_AVAILABLE
MQOO_BIND_NOT_FIXED 0x00008000 //MQGMO_LOGICAL_ORDER
在第二个以2046 (MQRC_OPTIONS_ERROR)
失败的示例中,因为选项被解释为如下所示。您在开放选项中不能同时拥有MQOO_INPUT_AS_Q_DEF
和MQOO_INPUT_SHARED
,这会导致2046
:
MQOO_INPUT_AS_Q_DEF 0x00000001
MQOO_INPUT_AS_Q_DEF 0x00000001 //MQGMO_WAIT
MQOO_RESOLVE_LOCAL_Q 0x00040000 //MQGMO_ALL_SEGMENTS_AVAILABLE
MQOO_RESOLVE_LOCAL_TOPIC 0x00040000 //MQGMO_ALL_SEGMENTS_AVAILABLE
MQOO_BIND_NOT_FIXED 0x00008000 //MQGMO_LOGICAL_ORDER
MQOO_INPUT_SHARED 0x00000002 //MQGMO_SYNCPOINT
在您使用2046 (MQRC_OPTIONS_ERROR)
失败的第三个示例中,这是因为选项被解释为如下所示。 MQOO_RESOLVE_NAMES
仅在MQ C ++ API中记录为有效,这会导致2046
:
MQOO_INPUT_AS_Q_DEF 0x00000001
MQOO_INPUT_AS_Q_DEF 0x00000001 //MQGMO_WAIT
MQOO_RESOLVE_NAMES 0x00010000 //MQGMO_COMPLETE_MSG
使用MQOO_INPUT_AS_Q_DEF
作为获取消息选项不会导致任何问题,因为它与您在每个示例中已有的MQGMO_WAIT
具有相同的值,这不会改变行为获取消息选项。
MQGMO_WAIT 0x00000001 //MQOO_INPUT_AS_Q_DEF
MQGMO_WAIT 0x00000001
基于您的第二个和第三个示例的以下内容应该有效:
public void getMessage(){
try {
MQEnvironment.hostname = "";
MQEnvironment.channel = "";
MQEnvironment.port = ;
MQQueueManager QMgr = new MQQueueManager("MQManager");
// Set up the options on the queue we wish to open
int openOptions = MQConstants.MQOO_INPUT_AS_Q_DEF;
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQConstants.MQGMO_WAIT|
MQConstants.MQGMO_ALL_SEGMENTS_AVAILABLE|
MQConstants.MQGMO_LOGICAL_ORDER|
MQConstants.MQGMO_SYNCPOINT|
MQConstants.MQGMO_COMPLETE_MSG;
gmo.matchOptions = MQConstants.MQMO_NONE;
gmo.waitInterval = MQConstants.MQWI_UNLIMITED;
MQMessage message = new MQMessage();
MQQueue queue = QMgr.accessQueue("QName", openOptions);
while(true){
queue.get(message, gmo);
int dataLength = message.getDataLength();
System.out.println(message.readStringOfCharLength(dataLength));
QMgr.commit();
message.clearMessage();
}
} catch (Exception e) {
e.printStackTrace();
}
}
如果运行完整MQ客户端安装附带的mqrc
实用程序,则可以找出错误代码转换为的内容:
$mqrc 2046
2046 0x000007fe MQRC_OPTIONS_ERROR