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

SimpMessagingTemplate.convertAndSend results in UnsupportedOperationException when Spring Cloud Sleuth is present #25821

Closed
rogue2yjg opened this issue Sep 26, 2020 · 5 comments
Assignees
Labels
in: messaging Issues in messaging modules (jms, messaging) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Milestone

Comments

@rogue2yjg
Copy link

rogue2yjg commented Sep 26, 2020

springboot version: 2.1.3
spring-websocket version: 5.1.1
spring-cloud-sleuth version: 2.1.1

When I try to use SimpMessagingTemplate.convertAndSend to send a String message to the websocket client after adding spring cloud sleuth to the application, an exception occurs:

Caused by: java.lang.UnsupportedOperationException: null
	at java.util.Collections$UnmodifiableMap.remove(Collections.java:1460)
	at org.springframework.messaging.support.NativeMessageHeaderAccessor.removeNativeHeader(NativeMessageHeaderAccessor.java:209)
	at org.springframework.cloud.sleuth.instrument.messaging.MessageHeaderPropagation.removeAnyTraceHeaders(MessageHeaderPropagation.java:86)
	at org.springframework.cloud.sleuth.instrument.messaging.TracingChannelInterceptor.preSend(TracingChannelInterceptor.java:173)
	at org.springframework.messaging.support.AbstractMessageChannel$ChannelInterceptorChain.applyPreSend(AbstractMessageChannel.java:178)
	at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:132)
	... 123 common frames omitted

some primary code belows:

@RequestMapping(value = "/ws/reply", method = RequestMethod.GET)
public String msgReply(@RequestParam String msg) {
	System.out.println(msg);
	template.convertAndSend("/riten_ws_topic", msg);
	return msg;
}
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
	@Override
	public void configureMessageBroker(MessageBrokerRegistry config) {
		config.enableSimpleBroker("/riten_ws_topic");
		config.setApplicationDestinationPrefixes("/riten_ws_client");
	}
	@Override
	public void registerStompEndpoints(StompEndpointRegistry registry) {
		registry.addEndpoint("/riten_ws_server").setAllowedOrigins("*").withSockJS();
	}
}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Sep 26, 2020
@jhoeller
Copy link
Contributor

There seems to be some internal state mismatch: Despite still being in mutable state (passing that assertion in removeNativeHeader), the header accessor seems to contain a "nativeHeaders" entry with an unmodifiable Map. Since we're always taking a defensive copy on regular NativeMessageHeaderAccessor construction, I wonder whether some external setHeader call was setting a custom unmodifiable "nativeHeaders" entry? @rstoyanchev Am I missing something here?

@jhoeller jhoeller added in: messaging Issues in messaging modules (jms, messaging) type: bug A general bug labels Sep 26, 2020
@rogue2yjg
Copy link
Author

Is there any way to solve the problem?@jhoeller @rstoyanchev

Now I have to delete the sleuth reference to use spring websocket.

@rstoyanchev
Copy link
Contributor

@rogue2yjg does this fail predictably every time? If you have something to reproduce with that we can debug that would be really helpful.

@rogue2yjg
Copy link
Author

rogue2yjg commented Sep 28, 2020

@rogue2yjg does this fail predictably every time? If you have something to reproduce with that we can debug that would be really helpful.

Yes, it fails every time, not surprisingly. The attach is my application to reproduce that, hoping that will be helpful.
You need use postman to simulate a get request which url is /ws/reply.

spring-websocket-server.zip

@rstoyanchev rstoyanchev self-assigned this Sep 28, 2020
@rstoyanchev rstoyanchev removed the status: waiting-for-triage An issue we've not yet triaged or decided on label Sep 29, 2020
@rstoyanchev rstoyanchev added this to the 5.2.10 milestone Sep 29, 2020
@rstoyanchev
Copy link
Contributor

Thanks for the sample, I was able to debug and find the issue in SimpleBrokerMessageHandler. It creates a copy of the message to broadcast for each subscriber and makes it mutable but the copying does not take proper care of the unmodifiable native headers sub-map so we end up in an inconsistent state.

I will work on a fix. In the mean time as a workaround you could install an interceptor on the clientOutboundChannel that makes the native headers modifiable:

@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {
	// Workaround for https://github.com/spring-projects/spring-framework/issues/25821
	registration.interceptors(new ChannelInterceptor() {
		@Override
		public Message<?> preSend(Message<?> message, MessageChannel channel) {
			MessageHeaderAccessor accessor = MessageHeaderAccessor.getMutableAccessor(message);
			accessor.setLeaveMutable(true);
			String key = NativeMessageHeaderAccessor.NATIVE_HEADERS;
			Map<String, List<String>> map = (Map<String, List<String>>) accessor.getHeader(key);
			if (map != null) {
				accessor.removeHeader(key);
				accessor.setHeader(key, new LinkedMultiValueMap<>(map));
			}
			return new GenericMessage<>(message.getPayload(), accessor.toMessageHeaders());
		}
	});
}

@spring-projects-issues spring-projects-issues added status: backported An issue that has been backported to maintenance branches and removed for: backport-to-5.1.x labels Sep 29, 2020
@rstoyanchev rstoyanchev changed the title SimpMessagingTemplate.convertAndSend throws UnsupportedOperationException after add spring cloud sleuth to application SimpMessagingTemplate.convertAndSend results in UnsupportedOperationException when Spring Cloud Sleuth is present Sep 29, 2020
rstoyanchev added a commit that referenced this issue Sep 30, 2020
rstoyanchev added a commit that referenced this issue Oct 1, 2020
zx20110729 pushed a commit to zx20110729/spring-framework that referenced this issue Feb 18, 2022
zx20110729 pushed a commit to zx20110729/spring-framework that referenced this issue Feb 18, 2022
zx20110729 pushed a commit to zx20110729/spring-framework that referenced this issue Feb 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: messaging Issues in messaging modules (jms, messaging) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

No branches or pull requests

4 participants