Skip to content

CAMEL-25950: camel-sjms - SjmsMessage keeps the attachments when the exchange is copied - #28644

Merged
davsclaus merged 3 commits into
apache:mainfrom
allthingssecurity:camel-sjms-message-copy-keeps-attachments
Oct 29, 2026
Merged

davsclaus merged 3 commits into
apache:mainfrom
allthingssecurity:camel-sjms-message-copy-keeps-attachments

Conversation

@allthingssecurity

@allthingssecurity allthingssecurity commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Description

CAMEL-25950

SjmsMessage.copyFrom overrides MessageSupport.copyFrom without calling it. It copies the body and the headers, but not the MessageTrait.ATTACHMENTS payload, where the attachments of a message are kept (camel-attachments AttachmentMessage stores them there).

So when an exchange received from an sjms endpoint is copied, the copy has no attachments. Multicast, Recipient List, Split and Wire Tap all work on copies, and so does a mock endpoint. A route like from("sjms:queue:in") that adds attachments and then multicasts or splits sends the copies on without them, and nothing is logged.

Until CAMEL-21755 (4.10.1) the attachments were exchange properties, and every exchange copy kept them. CAMEL-21755 moved them into a message trait, which only MessageSupport.copyFromWithNewBody copies. camel-jms had the same gap in JmsMessage.copyFrom: CAMEL-23193 fixed it, CAMEL-24365 removed that copy, and CAMEL-25779 (#28083) restored it. SjmsMessage never got the copy.

Changes:

  • SjmsMessage.copyFrom copies the ATTACHMENTS trait into a new map, the same way as MessageSupport and JmsMessage (CAMEL-25779: camel-jms: JmsMessage loses attachments when exchange is copied #28083).
  • camel-sjms2 uses the same SjmsMessage, so it is fixed as well.
  • A pooled SjmsMessage is not affected: DefaultMessage.reset() already removes the trait.
  • No option, generated file or upgrade guide change: nothing for users to migrate.
  • Backport candidates, for the maintainers to label if wanted (contributors cannot set port/* labels): camel-4.23.x and 4.22.x have the same SjmsMessage as main. camel-4.18.x and 4.14.x differ in other parts of the class, but their copyFrom does not copy the attachments either. I read the code on those branches but did not run the tests there.

Not changed: MailMessage.copyFrom (camel-mail) does not copy the trait either when mapMailMessage=false. In that mode the consumer does not extract attachments, so only attachments added by the route are affected. I can file a follow-up JIRA if wanted.

Tests:

  • New SjmsMessageCopyAttachmentsTest (JUnit assertions, as in the module). It uses the embedded in-VM Artemis broker of the other sjms tests (JmsTestSupport).
  • Fail on main:
    • multicastCopyKeepsTheAttachmentsOfAnSjmsMessage: a route from sjms adds an attachment and multicasts to a mock. Result: the copy made by the multicast must keep the attachments ==> expected: not <null>.
    • copyKeepsTheAttachments (SjmsMessage.copy()): copy() must keep the attachments ==> expected: not <null>.
  • copyOfAMessageWithoutAttachmentsHasNone is a control that passes on main and with the fix.
  • camel-sjms unit tests: 142 run, 0 failures, 5 skipped. After main was merged into the branch (review follow-up): camel-sjms 186 run, 0 failures, 5 skipped; camel-sjms2 28 run, 0 failures. The formatter and import-sort plugins ran. I built offline with -Dasm-version=9.11 because asm 9.11.1 was not in my local repository.

Target

  • I checked that the commit is targeting the correct branch (Camel 4 uses the main branch)

Tracking

  • If this is a large change, bug fix, or code improvement, I checked there is a JIRA issue filed for the change (usually before you start working on it): CAMEL-25950.

Apache Camel coding standards and style

  • I checked that each commit in the pull request has a meaningful subject line and body.
  • I have run mvn clean install -DskipTests locally from root folder and I have committed all auto-generated changes.
    (I built camel-sjms and ran its tests, including the formatter and import-sort plugins. No generated file changes. I did not run the full root build.)

AI-assisted contributions

  • If this PR includes AI-generated code, commits have proper co-authorship attribution (e.g., Co-authored-by trailers) and the PR description identifies the AI tool used.
    This PR was prepared with Claude Code (Claude Opus 5.5). The commit carries a Co-Authored-By trailer.

Claude Code on behalf of allthingssecurity

🤖 Generated with Claude Code

…exchange is copied

SjmsMessage.copyFrom overrides MessageSupport.copyFrom without calling it, and copies only the body and the headers.
Since CAMEL-21755 the attachments of a message are its ATTACHMENTS trait (before, they were exchange properties that
every exchange copy kept), so a copy of an exchange received from sjms lost them: Multicast, Recipient List, Split,
Wire Tap and the mock endpoint all work on copies. camel-jms had the same gap in JmsMessage, fixed by CAMEL-23193,
removed by CAMEL-24365 and fixed again by CAMEL-25779.

SjmsMessage.copyFrom now copies the ATTACHMENTS trait into a new map, as MessageSupport and JmsMessage do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@davsclaus davsclaus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as JmsMessage.copyFrom and MessageSupport.copyFromWithNewBody: the ATTACHMENTS trait is copied into a new map, newInstance() returns an SjmsMessage so the multicast copy goes through it, and sjms2 gets the fix too. Test style matches the module. Will approve once CI is green; the branch is ~330 commits behind main so a fresh merge run matters.

Suggestion: MessageSupport.copyFrom also copies the DATA_AWARE trait, SjmsMessage/JmsMessage do not (pre-existing, possible follow-up). Nit: unchecked cast without @SuppressWarnings.

Reviewed with Claude Code on behalf of @davsclaus. This review was generated by an AI agent and may contain inaccuracies; please verify all suggestions before applying.

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • components/camel-sjms

🔁 2 tests passed only after a retry on JDK 21 (2 retried attempts)

Recovered flaky tests on JDK 21 (2)
Module Test Failed attempts First failure
dsl/camel-jbang/camel-jbang-plugin-tui LaunchManagerOutcomeTest.startedWhenTheStatusFileSaysSo 1 expected: null but was: LaunchOutcome[ok=false, log=null]
dsl/camel-jbang/camel-jbang-plugin-tui MonitorStartupTest.browserOnlyServesUntilTheServerStops 1 Connection refused (connect failed)

ℹ️ These tests did not fail the build. Surefire retried them and they passed.
Retries are enabled project-wide by surefire.rerunFailingTestsCount in parent/pom.xml.


🔬 Scalpel shadow comparison — Scalpel: 10 of 709 tested, 27 compile-only — current: 10 all tested

Maveniverse Scalpel detected 10 affected modules (current approach: 10).

Skip-tests mode would test 10 modules (1 direct + 9 downstream), skip tests for 27 (generated code, meta-modules)

Modules Scalpel would test (10)
  • camel-jbang-mcp ← downstream of org.apache.camel:camel-catalog
  • camel-jbang-plugin-mcp ← downstream of org.apache.camel:camel-jbang-core
  • camel-jbang-plugin-tui ← downstream of org.apache.camel:camel-catalog
  • camel-jbang-plugin-validate ← downstream of org.apache.camel:camel-yaml-dsl-validator
  • camel-launcher-container ← downstream of org.apache.camel:camel-launcher
  • camel-mllp ← downstream of org.apache.camel:camel-sjms
  • camel-sjms ← components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsMessage.java, components/camel-sjms/src/test/java/org/apache/camel/component/sjms/SjmsMessageCopyAttachmentsTest.java
  • camel-sjms2 ← downstream of org.apache.camel:camel-sjms
  • camel-yaml-dsl-validator ← downstream of org.apache.camel:camel-catalog
  • camel-yaml-dsl-validator-maven-plugin ← downstream of org.apache.camel:camel-yaml-dsl-validator
Modules with tests skipped (27)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

All tested modules (37 modules, 6m 8s total)

Total reactor time: 6m 8s

Module Duration Status
Camel :: MLLP 56.6s SUCCESS
Camel :: JBang :: Plugin :: TUI 54.0s SUCCESS
Camel :: Launcher 44.3s SUCCESS
Camel :: Simple JMS2 24.1s SUCCESS
Camel :: JBang :: Plugin :: Validate 23.4s SUCCESS
Camel :: JBang :: MCP 20.8s SUCCESS
Camel :: YAML DSL :: Validator 20.0s SUCCESS
Camel :: YAML DSL 18.7s SUCCESS
Camel :: Catalog :: Camel Catalog 16.7s SUCCESS
Camel :: Component DSL 14.4s SUCCESS
Camel :: Kamelet Main 13.3s SUCCESS
Camel :: Docs 10.4s SUCCESS
Camel :: JBang :: Plugin :: Kubernetes 7.3s SUCCESS
Camel :: JBang :: Plugin :: Testing 6.8s SUCCESS
Camel :: YAML DSL :: Deserializers 5.7s SUCCESS
Camel :: Catalog :: Camel Route Parser 5.6s SUCCESS
Camel :: Catalog :: Camel Report Maven Plugin 5.4s SUCCESS
Camel :: All Components Sync point 3.5s SUCCESS
Camel :: YAML DSL :: Validator Maven Plugin 3.4s SUCCESS
Camel :: Catalog :: Maven 2.3s SUCCESS
Camel :: YAML DSL :: Maven Plugins 2.1s SUCCESS
Camel :: Catalog :: Suggest (deprecated) 1.3s SUCCESS
Camel :: Assembly 1.0s SUCCESS
Camel :: JBang :: Plugin :: Generate 0.9s SUCCESS
Camel :: Catalog :: Dummy Component 0.8s SUCCESS
Camel :: JBang :: Plugin :: Edit 0.8s SUCCESS
Camel :: Coverage 0.8s SUCCESS
Camel :: JBang :: Integration tests 0.7s SUCCESS
Camel :: Catalog :: Console 0.7s SUCCESS
Camel :: Endpoint DSL :: Support 0.6s SUCCESS
Camel :: Launcher :: Container 0.5s SUCCESS
Camel :: JBang :: Main 0.5s SUCCESS
Camel :: JBang :: Plugin :: MCP 0.5s SUCCESS
Camel :: Endpoint DSL n/a
Camel :: Integration Tests n/a
Camel :: JBang :: Core n/a
Camel :: Simple JMS n/a

Top 20 slowest modules:

  • Camel :: MLLP (56.6s)
  • Camel :: JBang :: Plugin :: TUI (54.0s)
  • Camel :: Launcher (44.3s)
  • Camel :: Simple JMS2 (24.1s)
  • Camel :: JBang :: Plugin :: Validate (23.4s)
  • Camel :: JBang :: MCP (20.8s)
  • Camel :: YAML DSL :: Validator (20.0s)
  • Camel :: YAML DSL (18.7s)
  • Camel :: Catalog :: Camel Catalog (16.7s)
  • Camel :: Component DSL (14.4s)
  • Camel :: Kamelet Main (13.3s)
  • Camel :: Docs (10.4s)
  • Camel :: JBang :: Plugin :: Kubernetes (7.3s)
  • Camel :: JBang :: Plugin :: Testing (6.8s)
  • Camel :: YAML DSL :: Deserializers (5.7s)
  • Camel :: Catalog :: Camel Route Parser (5.6s)
  • Camel :: Catalog :: Camel Report Maven Plugin (5.4s)
  • Camel :: All Components Sync point (3.5s)
  • Camel :: YAML DSL :: Validator Maven Plugin (3.4s)
  • Camel :: Catalog :: Maven (2.3s)

⚙️ View full build and test results

allthingssecurity and others added 2 commits October 29, 2026 11:19
…ttachments

The branch was about 330 commits behind main; merged (not rebased) so the review history stays.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed warning of the attachments cast

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@allthingssecurity

Copy link
Copy Markdown
Contributor Author

@davsclaus thanks for the review. Changes on top of the branch:

  • c691e02 merges current main into the branch (a merge commit, no rebase), as it was about 330 commits behind. git diff origin/main after the merge is only this PR's two files. With main merged, camel-sjms: 186 tests, 0 failures, 5 skipped; camel-sjms2: 28 tests, 0 failures; SjmsMessageCopyAttachmentsTest passed 20 runs in one JVM.
  • 4dc077c: @SuppressWarnings("unchecked") on the attachments cast in SjmsMessage.copyFrom.

Open follow-up: MessageSupport.copyFrom also copies the DATA_AWARE trait, and SjmsMessage/JmsMessage do not. That is older than this PR, so I would do it as a separate JIRA for both components rather than here.

Claude Code on behalf of allthingssecurity

@davsclaus davsclaus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes since my review address my points; CI is green. Thanks.

Reviewed with Claude Code on behalf of @davsclaus. This review was generated by an AI agent and may contain inaccuracies; please verify all suggestions before applying.

@davsclaus davsclaus added this to the 4.24.0 milestone Oct 29, 2026
@davsclaus davsclaus added the bug Something isn't working label Oct 29, 2026
@davsclaus
davsclaus merged commit cb59f8f into apache:main Oct 29, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working components components-jms

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants