The getBodyLength() implementation of my BytesMessageAdapter class looks like this:
Code:
private long getBodyLength() throws JMSException
{
// It is the responsibility of the caller to make sure that the
// BytesMessage is in read-only mode when this method is called
// as dictated by the JMS 1.1 API.
// The implementation of this method is very tricky because we
// need to make sure that the position of the stream is not
// affected by the invocation of this method. Since there is
// no way to find out what the current position of the stream
// is, we actually need to read through the whole message twice.
byte[] buffer = new byte[256 * 1024];
// First we read from the current position to the end of the
// message. This gives us lenMinusPosition and leaves the position
// at the end of the stream.
long lenMinusPosition = 0;
while (true) {
int read = message.readBytes(buffer);
if (read == -1) {
break;
}
lenMinusPosition = lenMinusPosition + read;
}
// Then we reset the message and read through the entire message.
// This gives us len.
message.reset();
long len = 0;
while (true) {
int read = message.readBytes(buffer);
if (read == -1) {
break;
}
len = len + read;
}
// From len and lenMinusPosition we can determine the original
// postion. We then reset the message again and read until the
// position.
long position = len - lenMinusPosition;
message.reset();
while (position > buffer.length) {
message.readBytes(buffer);
position = position - buffer.length;
}
if (position > 0) {
message.readBytes(buffer, (int) position);
}
// The message is now in the same state as before the method
// was invoked.
return len;
}
The whole adapter framework consists of 26 more Adapter and reverse Adapter classes so you were right in your observation that it is quite complex.
A simpler solution would be to wrap the current getBodyLength() call in a try/catch block, but this is really a clutch.
Code:
long len;
try {
len = bytesMessage.getBodyLength();
} catch (NoSuchMethodError eNoSuchMethod) {
len = getJMS102BodyLength(bytesMessage);
}
where the getJMS102BodyLength() method would be implemented as above.
Cheers,
Robin.