Repository navigation
Conversation
… null A JMS Message created with Session.createMessage() carries no body, and the client encoded it as an AMQP message with no body section at all. AMQP 1.0 section 3.2 does not allow that: it lists every other section as "zero or one", but the body as one of three mandatory choices (one or more data sections, one or more amqp-sequence sections, or a single amqp-value section). The AMQP JMS Mapping is explicit about which of those a bodiless JMS Message maps to - section 3.2.4.7 states that "a Message is encoded as a single amqp-value section containing null". Brokers that enforce the requirement therefore reject every message sent by Session.createMessage(); RabbitMQ, for instance, refuses the transfer with amqp:decode-error "missing_amqp_message_body", which fails a range of Jakarta Messaging TCK tests. Supply the amqp-value null section when encoding a facade that has no body. The fix is applied at the encode step rather than by giving the facade a body, so that the facade keeps representing "this message has no body" (as hasBody() and the JMS Message body accessors rely on) and so that a bodiless message received from a peer also gains a conformant body when forwarded. The x-opt-jms-msg-type annotation continues to identify the message as a generic Message on receipt; without it, an amqp-value null body would be read back as a TextMessage per the mapping's section 3.3.4. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
|
Hi @tabish121 @gemmellr, do you think we can get the PRs in
merged any time soon? Can we help in any way to get these PRs merged? |
|
I'll have written that mapping text after reading the same bit of the spec, but I recall this has since been discussed a few times long ago, with both the primary authors of the AMQP 1.0 spec indicating that their intent was for the body sectional to be optional like all the other message sections are (and themselves even writing earlier clients that do omit it). I know its also been discussed as something that could be revised in the spec, should it ever be updated. I dont know of any other server definitely having issue with this, but am aware of various clients (and possibly servers) that definitely can do it, so I would actually instead suggest you make RabbitMQ tolerate this instead of giving a decode error. I'll think on this some more, but I'm not sure I think it makes sense to have the clients (and potentially servers) defaulting to do the needless work of encoding and decoding to 'convey nothing' when its been the way it has for over a decade and various other clients have been doing the same for even longer, so I'd possibly even make it a flag if we did it at all. Either way, I would likely not implement it the way it has been here as a side effect of the AmqpCodec class, but within the message objects themselves. It would also need a Jira. |
|
Thank you @gemmellr for your reply. Two specifications unambiguously state that the current Qpid JMS client behaviour is a bug:
If there is a bug in the client, the client should be fixed, not the server.
Ok, please let us know if you want us to change this.
Ok, I created a Jira: https://issues.apache.org/jira/browse/QPIDJMS-633 |
|
No need to re-quote the spec+mapping, I'm aware of exactly what they say. I wrote the mapping, and discussed it and the spec text in this exact context with both of the key people that wrote that, who told me and others its text is imprecise/incorrect for the body definition when I and others have raised this to them previously (starting well over a decade ago). Both have written clients that omit bodies and so have various others, so its also a common deployed client and server behaviour at this point. I cant actually think of an implementation I am aware of that hasnt either now being doing this or handling this for approaching 15 years, except RabbitMQ. So I would again suggest you change the server to handle it, regardless of what happens with the Qpid JMS client. I'm not in a rush to change the client here at all given everything I've said, and I think what it does now is actually the most suited approach for the situation in general, so I do think maintaining the current behaviour by default still makes sense. If you want to add a toggled ability rather than making RabbitMQ tolerate the various existing clients feel free to update your PR accordingly, also moving the behaviour to the message itself rather than the encoding. |
Always send a body section, encoding a bodiless Message as amqp-value null.
A JMS Message created with
Session.createMessage()carries no body, and the client encoded it as an AMQP message with no body section at all.AMQP 1.0 section 3.2 does not allow that: it lists every other section as "zero or one", but the body as one of three mandatory choices (one or more data sections, one or more amqp-sequence sections, or a single amqp-value section). The AMQP JMS Mapping is explicit about which of those a bodiless JMS Message maps to - section 3.2.4.7 states that "a Message is encoded as a single amqp-value section containing null".
Brokers that enforce the requirement therefore reject every message sent by
Session.createMessage(); RabbitMQ, for instance, refuses the transfer with `amqp:decode-error "missing_amqp_message_body".Supply the amqp-value null section when encoding a facade that has no body. The fix is applied at the encode step rather than by giving the facade a body, so that the facade keeps representing "this message has no body" (as
hasBody()and the JMS Message body accessors rely on) and so that a bodiless message received from a peer also gains a conformant body when forwarded.The
x-opt-jms-msg-typeannotation continues to identify the message as a generic Message on receipt; without it, an amqp-value null body would be read back as a TextMessage per the mapping's section 3.3.4.