jsr343-experts@jms-spec.java.net

[jsr343-experts] Re: (JMS_SPEC-101) New method Message.getPayload(Class<T> c)

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Tue, 23 Oct 2012 19:01:23 +0100

On 23/10/2012 15:07, John D. Ament wrote:
> Ok, so looking throught it a bit more I think we have a few issues
>
> 1. You cannot pass byte[].class to the method (that's not a valid class). I think we need a work around here.

You can, actually :-)

> 2. I think the case should simply pass when Class.isAssignableFrom(Otherclass.class) is passed.

I like this general approach: the implementation extracts the payload, calls isAssignableFrom to see if this can be cast
to the required return type, and then performs the cast.

(If we adopt this approach we should change the JMSConsumer receivePayload methods to work in the same way)

> So if I pass in
> CharSequence.class, I should be able to get back a CharSequence in the following cases:

> - The message is a TextMessage, the underlying result is a String back (returned as a CharSequence instead)
>
> - The message is an ObjectMessage, the underlying type is an implementation of CharSequence (StringBuilder,
> StringBuffer, String).

Yes.

> IMHO from the initial messages about this method it seemed like the goal was to make the client ignorant (lack of a
> better term) to the fact that it's a text message or object message or map message.

> Also passing in Object.class should
> just return the payload, regardless of type, as long as it's not a StreamMessage.
>
> Thoughts?

Yes, though in this case the returned type would be an Object, so the application would need to perform a cast to do
anything useful with the payload.

Here's an updated javadoc. More views please!

        /**
         * Returns the messages's payload, which must be assignable to the specified
         * type. If the message has no payload then null is returned. This method
         * may be used to obtain the payload of any type of message except for
         * <tt>StreamMessage</tt>.
         *
         * @param c
         * The class of the payload.
         * <br/>
         * If the message is a <code>TextMessage</code> then this should
         * be set to <code>String.class</code> or any other class to
         * which a String is assignable.
         * <br/>
         * If the message is a <code>ObjectMessage</code> then this
         * should be set to <code>java.io.Serializable.class</code> or
         * any other class to which the payload is assignable.
         * <br/>
         * If the message is a <code>MapMessage</code> then this should
         * be set to <code>java.util.Map.class</code>.
         * <br/>
         * If the message is a <code>BytesMessage</code> then this should
         * be set to <code>byte[].class</code>.
         * <br/>
         * If the message is a <code>StreamMessage</code>, or the payload
         * cannot be assigned to the specified type a
         * <code>MessageFormatException</code> will be thrown
         *
         * @return the messages's payload
         *
         * @exception JMSException
         * if the JMS provider fails to get the payload due to some
         * internal error.
         * @exception MessageFormatException
         * if the message is a <code>StreamMessage</code>, or the
         * payload cannot be assigned to the specified type, or the
         * message is an ObjectMessage and object deserialization
         * fails.
         * @Exception MessageNotReadableException - if the message is a BytesMessage
         * and the message is in write-only mode.
         */
        <T> T getPayload(Class<T> c) throws JMSException;

Nigel