Skip to content

Commit 02b5827

Browse files
authored
GH-9369: Fix MutableMessageHeaders for serialization
Fixes: #9369 * Implement `MutableMessageHeaders.readResolve()` to reinstate the instance **Auto-cherry-pick to `6.3.x` & `6.2.x`**
1 parent f26d932 commit 02b5827

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

spring-integration-core/src/main/java/org/springframework/integration/support/MutableMessageHeaders.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.integration.support;
1818

19+
import java.io.ObjectStreamException;
20+
import java.io.Serial;
1921
import java.nio.ByteBuffer;
2022
import java.util.Map;
2123
import java.util.UUID;
@@ -31,6 +33,7 @@
3133
* @author David Turanski
3234
* @author Artem Bilan
3335
* @author Nathan Kurtyka
36+
* @author Mitchell McDonald
3437
*
3538
* @since 4.2
3639
*/
@@ -73,6 +76,11 @@ public Object remove(Object key) {
7376
return super.getRawHeaders().remove(key);
7477
}
7578

79+
@Serial
80+
private Object readResolve() throws ObjectStreamException {
81+
return new MutableMessageHeaders(this);
82+
}
83+
7684
@Nullable
7785
private static UUID extractId(@Nullable Map<String, Object> headers) {
7886
if (headers != null && headers.containsKey(MessageHeaders.ID)) {

spring-integration-core/src/test/java/org/springframework/integration/support/MutableMessageTests.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616

1717
package org.springframework.integration.support;
1818

19+
import java.io.ByteArrayInputStream;
20+
import java.io.ByteArrayOutputStream;
21+
import java.io.IOException;
22+
import java.io.ObjectInputStream;
23+
import java.io.ObjectOutputStream;
1924
import java.nio.ByteBuffer;
2025
import java.util.HashMap;
2126
import java.util.Map;
@@ -26,10 +31,12 @@
2631
import org.springframework.messaging.MessageHeaders;
2732

2833
import static org.assertj.core.api.Assertions.assertThat;
34+
import static org.assertj.core.api.Assertions.assertThatNoException;
2935

3036
/**
3137
* @author Stuart Williams
3238
* @author Nathan Kurtyka
39+
* @author Mitchell McDonald
3340
*
3441
* @since 4.2
3542
*/
@@ -104,4 +111,34 @@ public void testMessageHeaderIsSerializable() {
104111
assertThat(mutableMessageBytes.getHeaders().getTimestamp()).isEqualTo(timestamp);
105112
}
106113

114+
@Test
115+
public void testMessageHeaderIsSerializableAndDeserializableWithNonSerializableValues()
116+
throws IOException, ClassNotFoundException {
117+
118+
String payload = "payload";
119+
120+
Map<String, Object> headerMap = new HashMap<>();
121+
headerMap.put("header1", "serializableValue");
122+
headerMap.put("header2", new Object()); // Non-Serializable value
123+
124+
MutableMessage<String> mutableMessage = new MutableMessage<>(payload, headerMap);
125+
126+
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
127+
ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
128+
outputStream.writeObject(mutableMessage);
129+
outputStream.flush();
130+
131+
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
132+
ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream);
133+
Object deserializedObject = inputStream.readObject();
134+
135+
assertThat(deserializedObject).isInstanceOf(MutableMessage.class);
136+
MutableMessage<?> deserializedMessage =
137+
(MutableMessage<?>) deserializedObject;
138+
139+
assertThat(deserializedMessage.getHeaders().get("header2")).isNull(); // Non-serializable value removed
140+
assertThat(deserializedMessage.getHeaders().get("header1")).isEqualTo("serializableValue");
141+
assertThatNoException().isThrownBy(() -> deserializedMessage.getRawHeaders().put("header3", "newValue"));
142+
}
143+
107144
}

0 commit comments

Comments
 (0)