Skip to content

Bug: MessageListenerAdapter passes 'pattern' instead of 'channel' to 2-parameter delegate methods #3338

@rowland66

Description

@rowland66

Description

There is a discrepancy between the documentation, variable naming, and actual runtime behavior of MessageListenerAdapter. When using a delegate method with two parameters—typically handleMessage(T body, String channel)—the second parameter does not consistently contain the message's channel.

Instead, it passes the source of the event.

  • If using ChannelTopic: The source is the channel (Correct behavior).
  • If using PatternTopic: The source is the pattern string, not the specific channel that triggered the message (Incorrect/Unexpected behavior).

Since the 2-parameter delegate only receives the message body (already converted), the actual channel information is completely lost to the user. This is a critical issue when a single listener handles multiple channels via a pattern and needs to know the specific origin of the message.

Steps to Reproduce

  1. Configure a RedisMessageListenerContainer with a PatternTopic (e.g., orders.*).
  2. Set up a MessageListenerAdapter pointing to a delegate method: public void handleMessage(Object body, String channel)
  3. Publish a message to orders.electronics.
  4. Actual Result: The channel parameter receives "orders.*".
  5. Expected Result: The channel parameter should receive "orders.electronics".

Technical Context

The confusion likely stems from MessageListener.onMessage(Message message, byte[] pattern). While that interface provides the pattern as the second argument, it also provides the full Message object, which contains the channel.

In MessageListenerAdapter, the first argument is converted to the domain object (the body), leaving the second argument as the only place to provide metadata. The code currently prioritizes the pattern (the "source"), contradicting the documentation which refers to this parameter as channel or convertedChannel.

Proposed Solution

We should ensure the actual channel is passed as the second parameter by default, as this aligns with the parameter naming and developer expectations.

Suggested Changes

Update Delegation Logic: Modify MessageListenerAdapter line 247 to set the String convertedChannel to message.getChannel() instead of pattern.
Backward Compatibility: To avoid breaking existing implementations that rely on receiving the pattern, we could:

  • Add a configuration flag (e.g., setRetainPatternInDelegate(boolean)) to toggle behavior.
  • Support a 3-parameter delegate: handleMessage(T body, String channel, String pattern).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions