James Netherton created CAMEL-25779:
---------------------------------------
Summary: camel-jms: JmsMessage loses attachments when the
exchange is copied
Key: CAMEL-25779
URL: https://issues.apache.org/jira/browse/CAMEL-25779
Project: Camel
Issue Type: Bug
Components: camel-jms
Affects Versions: 4.23.0, 4.22.1, 4.22.0, 4.22.2
Reporter: James Netherton
When an exchange holding a {{JmsMessage}} is copied (for example by the
Multicast EIP), attachments on the message are lost. This was fixed in
CAMEL-23193 (4.18.2, 4.19.0) by copying the {{MessageTrait.ATTACHMENTS}}
payload in {{{}JmsMessage.copyFrom(){}}}.
CAMEL-24365 (4.22.0) removed that copy, treating it as a workaround for
{{exchange.getOut()}} that the new code in {{AbstractExchange.newOutMessage()}}
made redundant. But the two cover different code paths.
{{JmsMessage.copyFrom()}} overrides {{MessageSupport.copyFrom()}} without
calling super, so it never copies attachments, and {{newOutMessage()}} is not
involved when an exchange is copied.
h3. Reproducer
{code:java}
from("jms:queue:in")
.process(e -> e.getMessage(AttachmentMessage.class)
.addAttachment("text.txt", new DataHandler("Hello!", "text/plain")))
.multicast().stopOnException().shareUnitOfWork().synchronous()
.to("direct:downstream")
.end()
.log("after multicast: ${attachments}");
from("direct:downstream")
.process(e -> e.getMessage(AttachmentMessage.class)
.addAttachment("text2.txt", new DataHandler("Hello number 2!",
"text/plain")));
{code}
|| ||4.18.x||4.22.x / 4.23.0||
|Attachments seen in direct:downstream|[text.txt]|[]|
|Attachments after the multicast|[text.txt, text2.txt]|[text.txt]|
Full Quarkus reproducer from the user report:
[https://github.com/turing85/quarkus-camel-multicast-attachment]
h3. Fix
Restore the attachment copy in {{{}JmsMessage.copyFrom(){}}}, and add a
regression test. The original CAMEL-23193 fix had no test, which is why
removing it went unnoticed. A test that copies an exchange holding a
{{JmsMessage}} with an attachment, or runs it through a multicast, covers this
without a broker.
h3. Workaround
At the start of the route, replace the {{JmsMessage}} with a
{{{}DefaultMessage{}}}:
{code:java}
.process(exchange -> {
DefaultMessage message = new DefaultMessage(exchange);
message.copyFrom(exchange.getIn());
exchange.setIn(message);
})
{code}
Althoug, after this, the route no longer has access to the underlying
{{{}jakarta.jms.Message{}}}.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)