[
https://issues.apache.org/jira/browse/CAMEL-25779?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18128629#comment-18128629
]
Guillaume Nodet commented on CAMEL-25779:
-----------------------------------------
This issue is being investigated by a coding agent (on behalf of gnodet).
Root cause confirmed in JmsMessage.copyFrom() (lines 89-123): the method does
not call super.copyFrom() and manually copies body + headers but never copies
message traits, including MessageTrait.ATTACHMENTS. The parent
MessageSupport.copyFromWithNewBody() (line 232-235) correctly copies the
attachment trait map, but JmsMessage.copyFrom() bypasses it entirely.
Git history confirms the regression: commit 8731df17e97c (CAMEL-23193) added
the attachment copy, then commit 40ca925c96de (CAMEL-24365) removed it treating
it as a workaround made redundant by newOutMessage() -- but copyFrom() and
newOutMessage() cover different code paths.
Fix: add the attachment trait copy in JmsMessage.copyFrom() after the headers
copy, mirroring what MessageSupport.copyFromWithNewBody() does.
_Note: This comment was generated by an AI coding agent and requires manual
verification._
> 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.22.0, 4.22.1, 4.22.2, 4.23.0
> Reporter: James Netherton
> Assignee: Guillaume Nodet
> Priority: Major
>
> 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)