spring-cloud-sleuth: Error sending STOMP message via websocket
While upgrading from Spring Boot 2.0.5 to 2.1.1, I encountered a problem in a service which sends STOMP messages via a web socket. I have isolated the problem and created an example project:
https://github.com/purple52/websocket-sleuth-test
If you build that project and run the test using ./gradlew clean build --info
, it’ll fail with this error:
2019-01-17 10:01:14.876 ERROR [websocket-sleuth-test,86b7bbc97c2ae296,14d3361a3e31673e,false] 6022 --- [ Test worker] o.s.m.s.b.SimpleBrokerMessageHandler : Failed to send GenericMessage [payload=byte[16], headers={spanTraceId=86b7bbc97c2ae296, spanId=86b7bbc97c2ae296, simpMessageType=MESSAGE, nativeHeaders={spanTraceId=[86b7bbc97c2ae296], spanId=[86b7bbc97c2ae296], spanSampled=[0]}, spanSampled=0, contentType=application/json;charset=UTF-8, simpDestination=/topic/foo}]
2019-01-17 10:01:14.877 ERROR [websocket-sleuth-test,86b7bbc97c2ae296,86b7bbc97c2ae296,false] 6022 --- [ Test worker] o.s.m.s.ExecutorSubscribableChannel : Exception from afterMessageHandled in org.springframework.cloud.sleuth.instrument.messaging.TracingChannelInterceptor@3d415f8
I am not 100% sure this is a Cloud Sleuth defect, or whether it’s Spring Messaging at fault, but I’m starting by reporting it here, since my test passes if I remove Cloud Sleuth from the project. This is using version 2.0.2-RELEASE of Cloud Sleuth, but still happens if I override and use 2.1.0-RC3.
What appears to happen is that TracingChannelInterceptor
tries to remove the trace headers by calling NativeMessageHeaderAccessor.removeNativeHeader
which checks that the headers are mutable, then tries to remove the native header. However, although the accessor says it is mutable, the native headers are returned in an unmodifiable map which throws an UnsupportedOperationException
when the attempt is made to remove the headers.
You can see the full exception thrown with a breakpoint at AbstractMessageChannel.java#L142. Here’s the stacktrace:
java.lang.UnsupportedOperationException
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:158)
at org.springframework.cloud.sleuth.instrument.messaging.TracingChannelInterceptor.preSend(TracingChannelInterceptor.java:135)
at org.springframework.messaging.support.AbstractMessageChannel$ChannelInterceptorChain.applyPreSend(AbstractMessageChannel.java:178)
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:132)
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:122)
at org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler.lambda$sendMessageToSubscribers$0(SimpleBrokerMessageHandler.java:401)
at java.util.Map.forEach(Map.java:630)
at org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler.sendMessageToSubscribers(SimpleBrokerMessageHandler.java:388)
at org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler.handleMessageInternal(SimpleBrokerMessageHandler.java:304)
at org.springframework.messaging.simp.broker.AbstractBrokerMessageHandler.handleMessage(AbstractBrokerMessageHandler.java:256)
at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:144)
at org.springframework.messaging.support.ExecutorSubscribableChannel.sendInternal(ExecutorSubscribableChannel.java:100)
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:136)
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:122)
at org.springframework.messaging.simp.SimpMessagingTemplate.sendInternal(SimpMessagingTemplate.java:187)
at org.springframework.messaging.simp.SimpMessagingTemplate.doSend(SimpMessagingTemplate.java:162)
at org.springframework.messaging.simp.SimpMessagingTemplate.doSend(SimpMessagingTemplate.java:48)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:151)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:129)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:122)
at com.example.WebsocketTest.Can pass message via websocket(WebsocketTest.kt:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 24 (7 by maintainers)
Commits related to this issue
- Added a workaround for the mutability of native headers Since for some reason, the native headers sometimes are immutable even though the accessor says that the headers are mutable, then we have to e... — committed to spring-cloud/spring-cloud-sleuth by marcingrzejszczak 5 years ago
- Added a workaround for the mutability of native headers (#1323) Since for some reason, the native headers sometimes are immutable even though the accessor says that the headers are mutable, then we h... — committed to spring-cloud/spring-cloud-sleuth by marcingrzejszczak 5 years ago
- Passing a copy of headers - otherwise ConcurrentModificationException may happen fixes gh-1184 — committed to spring-cloud/spring-cloud-sleuth by marcingrzejszczak 4 years ago
- project update - update spring-boot to 2.4.3; - update spring-cloud to 2020.0.1; - update jib to 2.7.1; - update mapstruct to 1.4.2.Final; - update springdoc openapi to 1.5.4; - update openzipkin/zipk... — committed to ivangfr/springboot-kafka-websocket by deleted user 3 years ago
I’m working on this as we speak. The workaround is to disable Sleuth’s websocket messaging support via
spring.sleuth.integration.websockets.enabled=false