Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MessageHeaderAccessor's MutableMessageHeaders should be serializable [SPR-15262] #19827

Closed
spring-issuemaster opened this issue Feb 16, 2017 · 2 comments

Comments

@spring-issuemaster
Copy link
Collaborator

commented Feb 16, 2017

Artem Bilan opened SPR-15262 and commented

The test-case to play:

@Test
public void serializeMutableHeaders() throws Exception {
	Map<String, Object> headers = new HashMap<String, Object>();
	headers.put("foo", "bar");

	Message<String> message = new GenericMessage<>("test", headers);

	MessageHeaderAccessor mutableAccessor = MessageHeaderAccessor.getMutableAccessor(message);
	mutableAccessor.setContentType(MimeType.valueOf("text/plain"));

	message = new GenericMessage<>(message.getPayload(), mutableAccessor.getMessageHeaders());

	Message<?> output = (Message<?>) serializeAndDeserialize(message);
	assertEquals("test", output.getPayload());
	assertEquals("bar", output.getHeaders().get("foo"));
	assertNotNull(output.getHeaders().get(MessageHeaders.CONTENT_TYPE));
}

private static Object serializeAndDeserialize(Object object) throws Exception {
	ByteArrayOutputStream baos = new ByteArrayOutputStream();
	ObjectOutputStream out = new ObjectOutputStream(baos);
	out.writeObject(object);
	out.close();
	ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
	ObjectInputStream in = new ObjectInputStream(bais);
	Object result = in.readObject();
	in.close();
	return result;
}

Which ends up with the error:

java.io.NotSerializableException: org.springframework.messaging.support.MessageHeaderAccessor

	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at org.springframework.integration.message.MessageHeadersTests.serializeAndDeserialize(MessageHeadersTests.java:169)
	at org.springframework.integration.message.MessageHeadersTests.serializeMutableHeaders(MessageHeadersTests.java:160)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

The real use-case is here: https://github.com/spring-cloud/spring-cloud-sleuth/blob/master/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceChannelInterceptor.java#L85

The root cause is with an implicit property for outer class instance reference, which isn't Serializable.

I propose solution as make this MutableMessageHeaders static and provide an outer instance as an explicit property but with the transient modifier.

Although it might be much better do not expose this inner class to the user altogether...


Affects: 4.2.9, 4.3.6, 5.0 M4

Reference URL: http://stackoverflow.com/questions/42277170/messagedeliveryexception-thrown-when-using-amqp-backed-channel-with-brixton-sr7

Issue Links:

  • #16094 Support Mutable Messages with optional ID and timestamp headers

Referenced from: commits 74bdcd8, 9834c42

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Feb 16, 2017

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Feb 17, 2017

Juergen Hoeller commented

Good point. We're replacing MutableMessageHeaders with a regular MessageHeaders instance on serialization now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.