Skip to content

GH-6792: Add headers mapping to JMS channels#10838

Merged
cppwfs merged 2 commits into
spring-projects:mainfrom
artembilan:GH-6792
Feb 27, 2026
Merged

GH-6792: Add headers mapping to JMS channels#10838
cppwfs merged 2 commits into
spring-projects:mainfrom
artembilan:GH-6792

Conversation

@artembilan

Copy link
Copy Markdown
Member

Fixes: #6792

Currently, by default AbstractJmsChannel implementations use Java serialization for storing Message<?> instance into JMS destination. The deserialized message is produced from the channel as is. There might be use-cases when some JMS properties could be useful in downstream flows.

  • Add DefaultJmsHeaderMapper into the AbstractJmsChannel as a conditional logic to map headers to/from JMS when jmsTemplate.getMessageConverter() is not a MessagingMessageConverter. Otherwise, then conversion of the message and header mapping is done in that converter
  • Refactor logic in the AbstractJmsChannel to common API
  • Fix Nullability formatting in the PollableJmsChannel
  • Use lambda style for MessageListener in the SubscribableJmsChannel instead of inner extra class
  • Ensure in the PollableJmsChannelTests and SubscribableJmsChannelTests that header mapper does it job
  • Fix JmsChannelParserTests to not assert on the messageBuilderFactory since now a MessageListener in the SubscribableJmsChannel is a direct method of the class
  • Fix JmsChannelHistoryTests verification according to a new internal logic of the AbstractJmsChannel
  • Document new feature in the jms.adoc and whats-new.adoc

@artembilan artembilan requested a review from cppwfs February 26, 2026 18:28

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

Great work. Just a couple of nitpicks!

if (!(converter instanceof MessagingMessageConverter)) {
messageToSend = getMessageBuilderFactory()
.fromMessage(messageToSend)
.copyHeadersIfAbsent(this.headerMapper.toHeaders(message))

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.

Would a user want the original header overwritten? Is this an option we want to add?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah...
First of all I don't want to expose headers manipulation options from these channels at all.
And secondly, I followed exactly same logic as MessagingMessageConverter.
This our logic here is to mimic that converter when Message is deserialized as is without any JMS headers.
If header is present there in the message, then it is indeed end-user preference.
If something else should be done, the custom MessageConverter is welcome.
Just not header mapping from the channel configuration.

Comment thread src/reference/antora/modules/ROOT/pages/whats-new.adoc
Fixes: spring-projects#6792

Currently, by default `AbstractJmsChannel` implementations use Java serialization
for storing `Message<?>` instance into JMS destination.
The deserialized message is produced from the channel as is.
There might be use-cases when some JMS properties could be useful in downstream flows.

* Add `DefaultJmsHeaderMapper` into the `AbstractJmsChannel` as a conditional logic
to map headers to/from JMS when `jmsTemplate.getMessageConverter()` is not a `MessagingMessageConverter`.
Otherwise, then conversion of the message and header mapping is done in that converter
* Refactor logic in the `AbstractJmsChannel` to common API
* Fix Nullability formatting in the `PollableJmsChannel`
* Use lambda style for `MessageListener` in the `SubscribableJmsChannel`
instead of inner extra class
* Ensure in the `PollableJmsChannelTests` and `SubscribableJmsChannelTests`
that header mapper does it job
* Fix `JmsChannelParserTests` to not assert on the `messageBuilderFactory`
since now a `MessageListener` in the `SubscribableJmsChannel` is a direct method of the class
* Fix `JmsChannelHistoryTests` verification according to a new internal logic of the `AbstractJmsChannel`
* Document new feature in the `jms.adoc` and `whats-new.adoc`

# Conflicts:
#	src/reference/antora/modules/ROOT/pages/whats-new.adoc
* Use lambda-based `logger.debug()` in the `PollableJmsChannel` instead of `if (logger.isDebugEnabled()) {`:
the `message` variable is now effectively `final`
* Remove redundant null checks from the `SubscribableJmsChannel`
* Add more header tests into the `PollableJmsChannelTests` & `SubscribableJmsChannelTests`
* Clean up `JmsChannelParserTests` and verify the `messageBuilderFactory` settings

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

Love the cleanup above and beyond what I requested. This looks great!

LGTM!

@cppwfs cppwfs merged commit 62a99db into spring-projects:main Feb 27, 2026
3 checks passed
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.

Add header-mapper to int-jms:channel [INT-2816]

2 participants