Skip to content

Always send a body section - #73

Closed
ansd wants to merge 1 commit into
apache:mainfrom
ansd:null-body
Closed

ansd wants to merge 1 commit into
apache:mainfrom
ansd:null-body

Conversation

@ansd

@ansd ansd commented Aug 25, 2026

Copy link
Copy Markdown

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-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.

… 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]>
@ansd

ansd commented Sep 7, 2026

Copy link
Copy Markdown
Author

@gemmellr

gemmellr commented Sep 7, 2026

Copy link
Copy Markdown
Member

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.

@ansd

ansd commented Sep 7, 2026

Copy link
Copy Markdown
Author

Thank you @gemmellr for your reply.

Two specifications unambiguously state that the current Qpid JMS client behaviour is a bug:

  1. https://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-messaging-v1.0-os.html#section-message-format clearly states "zero or one" section for all non-body sections and requires at least one section for the body.
  2. The AMQP JMS mapping spec explains in section 3.2.4 how the different JMS body types map to AMQP 1.0 messages. For this issue, section 3.2.4.7 is the relevant one and unambiguously states that such a message must have a single amqp-value section containing null. This is additionally confirmed in Figure 3.9.

so I would actually instead suggest you make RabbitMQ tolerate this instead of giving a decode error.

If there is a bug in the client, the client should be fixed, not the server.

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.

Ok, please let us know if you want us to change this.

It would also need a Jira.

Ok, I created a Jira: https://issues.apache.org/jira/browse/QPIDJMS-633

@gemmellr

gemmellr commented Sep 7, 2026

Copy link
Copy Markdown
Member

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.

@ansd ansd closed this Sep 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants