I wrote a client to read segmented message sent via MQ but getting error message. Below code work perfectly fine but it read single message at time, Application has to concatenate the segmented message which is not what I wanted
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();
}
}
When I added MQGMO_SYNCPOINT to options, it fails with com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2046'.
Not sure why this fails, if I can atleast get this to work, I will be able to commit after safely processing all segmented message in the application.
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();
}
}
When I try to read segmented message as a single message; it fails with com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2046'.
I would appreciate if some could help solve this issue; I am not really sure what is wrong with the below code. This is my preferred way to read the segmented message.
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();
}
}
The issue is that you are using gmo.options
as the open options for the accessQueue
method and the get message options for the get
. You are mixing both open options and get message options into this field.
Each option is represented by a bit in the options field. When you use that field as the open options the bits are being interpreted by MQ as open options even if you specify get message options, conversely when you use the field as the get message options they are being interpreted by MQ as get message options.
Lets look at the values of each option you are specifying in the your samples represented as hex along with the equivalent open or get option based on the value:
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
Because you are incorrectly using this as open options with QMgr.accessQueue("QName",
gmo.options
);
MQ is interpreting this in unexpected ways.
For your first "working" example, the open options would be interpreted as specified below, these specific open options together would not cause any problems for local queues, this is why it is "working" even though it is not correct:
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
In your second example that fails with 2046 (MQRC_OPTIONS_ERROR)
it is because the options are being interpreted as specified below. You cannot have MQOO_INPUT_AS_Q_DEF
and MQOO_INPUT_SHARED
together in the open options, this causes the 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
In your third example that fails with 2046 (MQRC_OPTIONS_ERROR)
it is because the options are being interpreted as specified below. MQOO_RESOLVE_NAMES
is documented as valid only in the MQ C++ APIs, this causes the 2046
:
MQOO_INPUT_AS_Q_DEF 0x00000001
MQOO_INPUT_AS_Q_DEF 0x00000001 //MQGMO_WAIT
MQOO_RESOLVE_NAMES 0x00010000 //MQGMO_COMPLETE_MSG
Using the MQOO_INPUT_AS_Q_DEF
as a get message option is not causing any issues because it has the same value as MQGMO_WAIT
which you already have in each of your examples, having this is not changing the behavior of the get message options.
MQGMO_WAIT 0x00000001 //MQOO_INPUT_AS_Q_DEF
MQGMO_WAIT 0x00000001
The following based on your second and third examples should work:
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();
}
}
If you run the mqrc
utility that comes with full MQ client installs you can find out what the error code translates to:
$mqrc 2046
2046 0x000007fe MQRC_OPTIONS_ERROR