users@jms-spec.java.net

[jms-spec users] [jsr343-experts] Re: (JMS_SPEC-102) Make JMSConsumer.receivePayload methods consistent with Message.getBody

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Thu, 08 Nov 2012 19:20:24 +0000

On 26/10/2012 17:05, Nigel Deakin wrote:
> I have logged this JIRA issue:
> http://java.net/jira/browse/JMS_SPEC-102
> Make JMSConsumer.receivePayload methods consistent with Message.getBody
>
> JMS_SPEC_64 introduced a new interface JMSConsumer for JMS 2.0. This has methods receivePayload(Class<T> c),
> receivePayload(Class<T> c, long timeout) and receivePayloadNoWait(Class<T> c).
>
> JMS_SPEC-101 will introduce a new method getBody(Class<T> c).
>
> If JMS_SPEC-101 is agreed then the definition of receivePayload(Class<T> c), receivePayload(Class<T> c, long
> timeout) and receivePayloadNoWait(Class<T> c) should be amended to make it consistent with the definition of
> getBody(Class<T> c). Specifically, these methods should allow the specified class to be any type to which the
> message payload can be assigned.
>
> In addition, the name of these method should be changed to receiveBody(Class<T> c), receiveBody(Class<T> c, long
> timeout) and receiveBodyNoWait(Class<T> c) since the word "payload" is inconsistent with the term "body" which is
> used in JMS 1.1.
>
> I will wait until JMS_SPEC-101 is resolved. Then I will make some more specific proposals for changes to receivePayload
> and receivePayloadNoWait for you to review.

Now I've deemed JMS_SPEC-101 to be agreed we can now do JMS_SPEC-102, which is
(1) to rename the receivePayload methods on JMSConsumer to receiveBody (for consistency) and
(2) to change them to use the specified type in the same way as the getBody method on Message.

The updated API docs can be reviewed at
http://jms-spec.java.net/2.0-SNAPSHOT/apidocs/javax/jms/JMSConsumer.html#receiveBody%28java.lang.Class%29

I've also pasted the source for one of these methods below. The definition is now very similar to the getBody method on
Message. The only difference is that if the message has no payload then instead of returning null these methods throw an
exception. That is because a return value of null needs to mean "no message available".

I think the way the specified type is handled is an improvement because it now allows ObjectMessages to be handled
better. I am less excited about renaming the method, but I think it is better to be consistent with the rest of the spec.

Nigel

        /**
         * Receives the next message produced for this {_at_code JMSConsumer} and
         * returns its body as an object of the specified type.
         * The message body must be capable of being assigned to the specified type.
         * This means that the specified class or interface must either be the same as,
         * or a superclass or superinterface of, the class of the message body.
         * This method may be used for messages of type
         * {_at_code TextMessage}, {_at_code BytesMessage}, {_at_code MapMessage} and {_at_code ObjectMessage}.
         * If the message is not one of these types, or its body cannot be assigned to the specified type,
         * or it has no body, then a {_at_code MessageFormatRuntimeException} is thrown and the message
         * will not be delivered.
         * <P>
         * This call blocks indefinitely until a message is produced or until this
         * {_at_code JMSConsumer} is closed.
         * <p>
         * <P>
         * If {_at_code receiveBody} is called within a transaction, the
         * {_at_code JMSConsumer} retains the message until the transaction commits.
         *
         * @param c
         * The type to which the body of the next message should be assigned.<br/>
         * If the next message is expected to be a {_at_code TextMessage} then
         * this should be set to {_at_code String.class}
          * or another class to which a {_at_code String} is assignable.<br/>
         * If the next message is expected to be a {_at_code ObjectMessage} then
         * this should be set to {_at_code java.io.Serializable.class}
          * or another class to which the body is assignable. <br/>
         * If the next message is expected to be a {_at_code MapMessage} then this
         * should be set to {_at_code java.util.Map.class}.<br/>
         * If the next message is expected to be a {_at_code BytesMessage} then this
         * should be set to {_at_code byte[].class}.<br/>
         *
         * @return the body of the next message produced for this
         * {_at_code JMSConsumer}, or null if this {_at_code JMSConsumer} is
         * concurrently closed
         *
         * @throws JMSRuntimeException
         * if the JMS provider fails to receive the next message due
         * to some internal error
         * @throws MessageFormatRuntimeException
         * if the message is not one of the supported types listed above,
         * or the message body cannot be assigned to the specified type,
         * or the message has no body,
         * or the message is an {_at_code ObjectMessage} and object deserialization fails.
         */
     <T> T receiveBody(Class<T> c);