Skip to content

Serializing MutableMessageHeaders containing a non-serializable header property results in serializer incorrectly serializing the 'headers' property on the class #9369

Closed
@mitchmcd18

Description

@mitchmcd18

In what version(s) of Spring Integration are you seeing this issue?

v6.2.7

Describe the bug

When MutableMessageHeaders is serialized using Spring Cores DefaultSerializer with a header that is not serializable it can result in the 'headers' property on the class being serialized as the superclass (MessageHeaders) instead of a HashMap. When deserialized this causes the 'headers' property to be an instance of MessageHeaders which prevents callers from adding properties to the MutableMessageHeaders class (When they should be able to). The following error is observed

Exception in thread "main" java.lang.UnsupportedOperationException: MessageHeaders is immutable
	at org.springframework.messaging.MessageHeaders.put(MessageHeaders.java:274)
	at org.springframework.messaging.MessageHeaders.put(MessageHeaders.java:73)
	at org.springframework.integration.support.MutableMessageHeaders.put(MutableMessageHeaders.java:63)

This looks to be related to the writeObject on the MessageHeaders class which will instantiate a new instance of the MessageHeaders class if there is a non-serializable object in the headers. Its likely that similar functionality needs to be overridden in the MutableMessageHeaders class in order to serialize it correctly. (See https://github.com/spring-projects/spring-framework/blob/main/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java#L307)

If there is no non-serializable objects in the headers then the MutableMessageHeaders works as expected when deserialized, this is because it just writes the object directly in the writeObject method rather than creating a new instance of MessageHeaders

This issue was originally observed when using the RedisMessageStore with an aggregator which under the hood makes use of the DefaultSerializer class, when I enabled observations it attempted to add the traceparent to the message header after it had been deserialized which then resulted in a failure.

To Reproduce

  1. Create a MutableMessageHeaders instance with a header value containing a non-serializable instance
  2. Serialize the class using the SerializingConverter
  3. Deserialize the class using the DeserializingConverter using the output from step 2
  4. Attempt to put a header into the deserialized MutableMessageHeaders instance

Expected behavior

Its expected that when MutableMessageHeaders is deserialized back into the object that it should be able to behave as normal and allow headers to be added using the classes 'put' method.

Sample

Link to sample showing bug: https://github.com/mitchmcd18/spring-messageheader-bug

Related links
https://github.com/spring-projects/spring-framework/blob/main/spring-core/src/main/java/org/springframework/core/serializer/support/SerializingConverter.java
https://github.com/spring-projects/spring-framework/blob/main/spring-core/src/main/java/org/springframework/core/serializer/support/DeserializingConverter.java
https://github.com/spring-projects/spring-integration/blob/main/spring-integration-core/src/main/java/org/springframework/integration/support/MutableMessageHeaders.java

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions