Skip to content

Commit 2c47b2b

Browse files
mitchmcd18spring-builds
authored andcommitted
GH-9369: Fix MutableMessageHeaders for serialization
Fixes: #9369 * Implement `MutableMessageHeaders.readResolve()` to reinstate the instance (cherry picked from commit 02b5827)
1 parent 7238432 commit 2c47b2b

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;
@@ -32,6 +34,7 @@
3234
* @author David Turanski
3335
* @author Artem Bilan
3436
* @author Nathan Kurtyka
37+
* @author Mitchell McDonald
3538
*
3639
* @since 4.2
3740
*/
@@ -74,6 +77,11 @@ public Object remove(Object key) {
7477
return super.getRawHeaders().remove(key);
7578
}
7679

80+
@Serial
81+
private Object readResolve() throws ObjectStreamException {
82+
return new MutableMessageHeaders(this);
83+
}
84+
7785
@Nullable
7886
private static UUID extractId(@Nullable Map<String, Object> headers) {
7987
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,11 +31,13 @@
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
/**
3238
* @author Stuart Williams
3339
* @author Nathan Kurtyka
40+
* @author Mitchell McDonald
3441
*
3542
* @since 4.2
3643
*/
@@ -105,4 +112,34 @@ public void testMessageHeaderIsSerializable() {
105112
assertThat(mutableMessageBytes.getHeaders().getTimestamp()).isEqualTo(timestamp);
106113
}
107114

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

0 commit comments

Comments
 (0)