Skip to content

Fix IBM MQ 10.0 upgrade: handle reserved JMS vendor properties - #25232

Open
gnodet wants to merge 2 commits into
apache:mainfrom
gnodet:fix/ibmmq-10-upgrade-with-lang-fix
Open

Fix IBM MQ 10.0 upgrade: handle reserved JMS vendor properties#25232
gnodet wants to merge 2 commits into
apache:mainfrom
gnodet:fix/ibmmq-10-upgrade-with-lang-fix

Conversation

@gnodet

@gnodet gnodet commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Claude Code on behalf of Guillaume Nodet

Summary

Upgrade IBM MQ client library and container image to version 10.0, and fix a compatibility issue where IBM MQ 10.0 marks the JMS_IBM_MsgToken vendor property as read-only.

This is a follow-up to #25107 which identified the upgrade but had test failures.

Changes

  • parent/pom.xml: Upgrade com.ibm.mq:com.ibm.mq.jakarta.client from 9.4.5.1 to 10.0.0.0
  • test-infra/camel-test-infra-ibmmq/src/test/resources/container.properties: Upgrade container image from icr.io/ibm-messaging/mq:9.4.5.0-r2 to icr.io/ibm-messaging/mq:10.0.0.0-r2
  • components/camel-jms/src/main/java/.../JmsBinding.java: Add defensive try-catch in appendJmsProperty() for JMS vendor-specific properties (JMS_* prefix per JMS spec section 3.5.1) that the provider marks as reserved/read-only. Non-vendor properties still throw on failure as before.
  • components/camel-jms/src/test/java/.../JmsReplyToIbmMQTest.java: Modernized test (dropped public, switched to AssertJ assertions)
  • docs/.../camel-4x-upgrade-guide-4_22.adoc: Added upgrade guide entries for the IBM MQ 10.0 upgrade and the behavioral change
  • Generated metadata files: Updated serviceVersion in IBM MQ test-infra JSON files

Root Cause

IBM MQ 10.0 marks JMS_IBM_MsgToken as a reserved property that cannot be set by applications. When Camel copies all headers from an incoming JMS message to an outgoing reply, JmsBinding.appendJmsProperty() attempted to set this reserved property, causing a MessageFormatException. This exception propagated up through Spring's DefaultMessageListenerContainer, preventing the reply from being sent — resulting in the test receiving null instead of the expected response.

The fix catches JMSException only for JMS vendor-specific properties (JMS_* prefix) and logs at WARN level, while re-throwing for non-vendor properties. There is no standard JMS API to query which vendor properties are reserved, and the set can change between provider versions.

Test Plan

  • JmsReplyToIbmMQTest.testCustomJMSReplyToInOut passes with IBM MQ 10.0
  • Full CI green

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

@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • catalog/camel-catalog
  • components/camel-jms
  • docs
  • parent
  • test-infra/camel-test-infra-all
  • test-infra/camel-test-infra-ibmmq

🔬 Scalpel shadow comparison — Scalpel: 16 tested, 27 compile-only — current: 14 all tested

Maveniverse Scalpel detected 43 affected modules (current approach: 14).

⚠️ Modules only in Scalpel (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • 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

Changed properties: com-ibm-mq-jakarta-client-version

Skip-tests mode would test 16 modules (5 direct + 11 downstream), skip tests for 27 (generated code, meta-modules)

Modules Scalpel would test (16)
  • camel-activemq
  • camel-activemq6
  • camel-amqp
  • camel-catalog
  • camel-jbang-mcp
  • camel-jbang-plugin-mcp
  • camel-jbang-plugin-route-parser
  • camel-jbang-plugin-tui
  • camel-jbang-plugin-validate
  • camel-jms
  • camel-launcher-container
  • camel-test-infra-all
  • camel-test-infra-ibmmq
  • camel-yaml-dsl-validator
  • camel-yaml-dsl-validator-maven-plugin
  • docs
Modules with tests skipped (27)
  • apache-camel
  • camel-allcomponents
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • 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
  • dummy-component

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

⚠️ Some tests are disabled on GitHub Actions (@DisabledIfSystemProperty(named = "ci.env.name")) and require manual verification:

  • components/camel-jms: 1 test(s) disabled on GitHub Actions
All tested modules (43 modules)
  • Camel :: AMQP
  • Camel :: ActiveMQ 5.x
  • Camel :: ActiveMQ 6.x
  • Camel :: All Components Sync point
  • Camel :: Assembly
  • Camel :: Catalog :: CSimple Maven Plugin (deprecated)
  • Camel :: Catalog :: Camel Catalog
  • Camel :: Catalog :: Camel Report Maven Plugin
  • Camel :: Catalog :: Camel Route Parser
  • Camel :: Catalog :: Console
  • Camel :: Catalog :: Dummy Component
  • Camel :: Catalog :: Lucene (deprecated)
  • Camel :: Catalog :: Maven
  • Camel :: Catalog :: Suggest
  • Camel :: Component DSL
  • Camel :: Coverage
  • Camel :: Docs
  • Camel :: Endpoint DSL
  • Camel :: Endpoint DSL :: Support
  • Camel :: Integration Tests
  • Camel :: JBang :: Core
  • Camel :: JBang :: Integration tests
  • Camel :: JBang :: MCP
  • Camel :: JBang :: Main
  • Camel :: JBang :: Plugin :: Edit
  • Camel :: JBang :: Plugin :: Generate
  • Camel :: JBang :: Plugin :: Kubernetes
  • Camel :: JBang :: Plugin :: MCP
  • Camel :: JBang :: Plugin :: Route Parser
  • Camel :: JBang :: Plugin :: TUI
  • Camel :: JBang :: Plugin :: Testing
  • Camel :: JBang :: Plugin :: Validate
  • Camel :: JMS
  • Camel :: Kamelet Main
  • Camel :: Launcher
  • Camel :: Launcher :: Container
  • Camel :: Test Infra :: All test services
  • Camel :: Test Infra :: IBM MQ
  • Camel :: YAML DSL
  • Camel :: YAML DSL :: Deserializers
  • Camel :: YAML DSL :: Maven Plugins
  • Camel :: YAML DSL :: Validator
  • Camel :: YAML DSL :: Validator Maven Plugin

⚙️ View full build and test results

@gnodet gnodet changed the title chore(deps): upgrade IBM MQ to 10.0 with CCSID fix Fix IBM MQ 10.0 upgrade: handle reserved JMS vendor properties Jul 30, 2026
Upgrades IBM MQ container (9.4.5.0-r2 → 10.0.0.0-r2) and client library
(9.4.5.1 → 10.0.0.0).

IBM MQ 10.0 marks JMS_IBM_MsgToken as a reserved read-only property.
When Camel copies headers from an incoming JMS message to an outgoing
reply or forwarded message, it attempts to set all JMS_IBM_* properties
on the new message, causing JMSCC0050 (MessageFormatException) which
crashes the reply send, resulting in null replies.

The fix wraps the property-setting call in JmsBinding.appendJmsProperty()
with a try-catch that gracefully skips any property the JMS provider
considers reserved or read-only. This defensive approach works for any
JMS vendor, not just IBM MQ.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet
gnodet force-pushed the fix/ibmmq-10-upgrade-with-lang-fix branch from dd5f83d to 2a4aabd Compare July 31, 2026 05:20
@gnodet
gnodet marked this pull request as ready for review July 31, 2026 05:20
@gnodet
gnodet requested review from davsclaus and oscerd July 31, 2026 05:20

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Claude Code on behalf of Guillaume Nodet

The code fix itself is sound — defensively catching exceptions around setProperty to handle reserved JMS vendor properties (like IBM MQ 10.0's JMS_IBM_MsgToken) is a well-reasoned approach that follows existing codebase patterns (e.g., JmsMessageHelper.setCorrelationId at line 184-190). The broad JMSException catch is appropriate for multi-provider compatibility since the JMS spec only declares throws JMSException on setXxxProperty methods. CI is green and the test modernization correctly follows project conventions.

Two documentation items to consider:


🟡 Missing upgrade guide entry for IBM MQ client 9.x → 10.x

The upgrade guide (camel-4x-upgrade-guide-4_22.adoc) documents other major dependency bumps in this release (Debezium 3.5.2→3.6.0, Smack 4.3→4.4, Weaviate v5→v6). The IBM MQ client library jump from 9.4.5.1 to 10.0.0.0 is a major version change that introduced behavioral differences (reserved JMS_IBM_MsgToken property). Users who depend on IBM MQ-specific behavior or pin their IBM MQ client version should be informed.

🟡 Behavioral change applies to all JMS providers

Before this change, a JMSException from JmsMessageHelper.setProperty would propagate up through appendJmsProperty, potentially causing outgoing message creation to fail. After this change, such exceptions are caught and logged at DEBUG level only, with the property silently skipped. This applies to all JMS providers, not just IBM MQ. Users who relied on exception propagation (e.g., for custom error handling or detecting when critical properties fail to set) would experience different behavior. This behavioral change should also be noted in the upgrade guide.

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

I think the behavorial change and major library upgrade must be documented as mentioned here #25232 (review)

are there ways to know about the reserved JMS vendor properties list? So that we skip them with a warning but continue to throw an exeption when it is a different problem?

- Only catch JMSException for JMS vendor-specific properties (JMS_* prefix
  per JMS spec section 3.5.1), re-throw for non-vendor properties
- Log at WARN level instead of DEBUG for better visibility
- Add upgrade guide entries for IBM MQ 10.0 upgrade and the behavioral
  change in JmsBinding.appendJmsProperty()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet

gnodet commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

Claude Code on behalf of Guillaume Nodet

@apupier Thanks for the review! Both points addressed in the latest push:

1. Narrowed the catch scope:
The JMSException catch now only applies to JMS vendor-specific properties (those with a JMS_ prefix, per JMS spec section 3.5.1). For all other properties, the exception is re-thrown as before — so there is no behavioral change for user-defined properties. The log level has also been raised from DEBUG to WARN for better visibility.

Regarding your question about a reserved properties list: there is no standard JMS API to query which vendor properties are reserved. The set varies by provider and can change between versions (IBM MQ 10.0 made JMS_IBM_MsgToken read-only, which was writable in 9.x). The JMS_ prefix check is the most reliable approach — it matches exactly the vendor-specific namespace defined in the JMS specification, and only those properties can be provider-reserved.

2. Upgrade guide entries added:
Two new sections in camel-4x-upgrade-guide-4_22.adoc:

  • camel-jms - IBM MQ client upgraded to 10.0 — documents the major version bump
  • camel-jms - vendor-specific JMS properties skipped when read-only — documents the behavioral change, noting it only affects JMS_-prefixed properties

@github-actions github-actions Bot added the docs label Jul 31, 2026
@gnodet
gnodet requested a review from apupier July 31, 2026 10:12

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Re-review after new commits addressing review feedback: the second commit cleanly addresses all prior review points — the catch scope is narrowed to JMS vendor-specific properties only (JMS_ prefix per JMS spec section 3.5.1), logging is elevated to WARN, and thorough upgrade guide entries document both the IBM MQ 10.0 major version bump and the behavioral change in JmsBinding. CI is green. LGTM ✅

Claude Code on behalf of Guillaume Nodet

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants