I am reading a message via JMX. If it is text then everything is OK, but if it is byte then it gives such an error. I can't figure out how I should read a byte message and get its text in a string.
Here's my Java code:
public static JMXMessage showMessage(QueueControl queueControl) {
JMXHeaders jmxHeaders;
JMXMessage jmxMessage;
String body;
String replyTo = null;
String correlationId = null;
try {
CompositeData[] messages = queueControl.browse();
j = queueLength - i;
if (j > queueLength - 1) {
i = 1;
j = queueLength - i;
}
if (j < 0) {
i = queueLength;
j = 0;
}
TabularData stringProps = (TabularData) messages[j].get(CompositeDataConstants.STRING_PROPERTIES);
for (CompositeData o : (Collection<CompositeData>) stringProps.values()) {
Object key = o.get("key");
if (key.equals("JMSReplyTo")) {
replyTo = o.get("value").toString();
}
if (key.equals("JMSCorrelationID")) {
correlationId = o.get("value").toString();
}
}
jmxHeaders = new JMXHeaders(messages[j].get(CompositeDataConstants.TYPE).toString(),
messages[j].get(CompositeDataConstants.EXPIRATION).toString(),
messages[j].get(CompositeDataConstants.DURABLE).toString(),
replyTo,
messages[j].get(CompositeDataConstants.MESSAGE_ID).toString(),
messages[j].get(CompositeDataConstants.TIMESTAMP).toString(),
correlationId,
messages[j].get(CompositeDataConstants.PRIORITY).toString());
body = (String) messages[j].get(CompositeDataConstants.TEXT_BODY);
jmxMessage = new JMXMessage(jmxHeaders, body);
return jmxMessage;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Error code:
Caused by: java.lang.RuntimeException: javax.management.openmbean.InvalidKeyException: Argument key="text" is not an existing item name for this CompositeData instance.
at jmxClientUIPConsole.BuildGet.showMessage(BuildGet.java:155)
at jmxClientUIPConsole.DConsoleFrameControllerGetMessage.viewMessage(DConsoleFrameControllerGetMessage.java:166)
... 62 more
Caused by: javax.management.openmbean.InvalidKeyException: Argument key="text" is not an existing item name for this CompositeData instance.
at java.management/javax.management.openmbean.CompositeDataSupport.get(CompositeDataSupport.java:270)
at jmxClientUIPConsole.BuildGet.showMessage(BuildGet.java:150)
... 63 more
That is the error in this line:
body = (String) messages[j].get(CompositeDataConstants.TEXT_BODY);
How can I then determine in this method what message came to me (byte or text)? And how do I get the message in bytes from the queue?
The bodies of a JMS BytesMessage
and TextMessage
are serialized differently because the former is a byte[]
and the latter is a String
. You are attempting to get the text body out of a BytesMessage
which doesn't exist and therefore you receive the InvalidKeyException
.
However, you can detect the kind of message it is and then adjust accordingly, e.g.:
QueueControl queueControl = ...
CompositeData[] messages = queueControl.browse();
for (CompositeData message : messages) {
if ((byte) message.get(CompositeDataConstants.TYPE) == (byte) 4) {
System.out.println("This is a BytesMessage");
} else {
System.out.println("This is a TextMessage");
}
}
If you want to get the byte[]
body of the message you can do so like this:
byte[] body = (byte[]) message.get(CompositeDataConstants.BODY);
Of course, in order to actually decode they byte[]
into a String
for example you'll need to know how it was encoded in the first place. String
objects in Java can be encoded many different ways although the most common is probably using UTF-8 in which case the code would look something like:
String body = Strings.getString((byte[]) message.get(CompositeDataConstants.BODY), StandardCharsets.UTF_8);