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

ConcurrentModificationException when calling SimpMessagingTemplate.convertAndSend [SPR-13185] #17777

Closed
spring-issuemaster opened this issue Jul 2, 2015 · 6 comments
Assignees
Milestone

Comments

@spring-issuemaster
Copy link
Collaborator

@spring-issuemaster spring-issuemaster commented Jul 2, 2015

Henrik Olsson opened SPR-13185 and commented

18:35:42.312 [http-nio-8080-exec-47] ERROR o.s.w.s.m.StompSubProtocolHandler - Error publishing SessionSubscribeEvent[GenericMessage [payload=byte[0], headers={simpMessageType=SUBSCRIBE, stompCommand=SUBSCRIBE, nativeHeaders={id=[/api/event-lists/list], destination=[/api/event-lists/list]}, simpSessionAttributes={scopedTarget.scopedRequestsPerSessionCounter=session.ScopedRequestsPerSessionCounter@48538a7d, org.springframework.messaging.simp.SimpAttributes.DESTRUCTION_CALLBACK.scopedTarget.scopedRequestsPerSessionCounter=org.springframework.beans.factory.support.DisposableBeanAdapter@46758ba2}, simpSubscriptionId=/api/event-lists/list, simpSessionId=ialw0jal, simpDestination=/api/event-lists/list}]].
org.springframework.messaging.MessageDeliveryException: Failed to handle GenericMessage [payload=byte[3067], headers={simpMessageType=MESSAGE, stompCommand=SEND, nativeHeaders={id=[/api/event-lists/list], destination=[/api/event-lists/list], type=[FULL], simpOrigDestination=[/user/request-response]}, simpSessionAttributes={scopedTarget.scopedRequestsPerSessionCounter=session.ScopedRequestsPerSessionCounter@48538a7d, org.springframework.messaging.simp.SimpAttributes.DESTRUCTION_CALLBACK.scopedTarget.scopedRequestsPerSessionCounter=org.springframework.beans.factory.support.DisposableBeanAdapter@46758ba2}, simpSubscriptionId=/api/event-lists/list, contentType=application/json;charset=UTF-8, simpSessionId=ialw0jal, simpDestination=/request-response-userialw0jal}] to org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask@fe59cf8 in SimpleBroker[DefaultSubscriptionRegistry[cache[509 destination(s)], registry[584 sessions]]]; nested exception is java.util.ConcurrentModificationException
        at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:144) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.support.ExecutorSubscribableChannel.sendInternal(ExecutorSubscribableChannel.java:91) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:117) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:104) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.simp.SimpMessagingTemplate.sendInternal(SimpMessagingTemplate.java:184) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.simp.SimpMessagingTemplate.doSend(SimpMessagingTemplate.java:176) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.simp.SimpMessagingTemplate.doSend(SimpMessagingTemplate.java:47) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:95) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.simp.user.UserDestinationMessageHandler.handleMessage(UserDestinationMessageHandler.java:190) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:135) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.support.ExecutorSubscribableChannel.sendInternal(ExecutorSubscribableChannel.java:91) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:117) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:104) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.simp.SimpMessagingTemplate.sendInternal(SimpMessagingTemplate.java:184) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.simp.SimpMessagingTemplate.doSend(SimpMessagingTemplate.java:176) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.simp.SimpMessagingTemplate.doSend(SimpMessagingTemplate.java:47) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:95) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:133) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.simp.SimpMessagingTemplate.convertAndSendToUser(SimpMessagingTemplate.java:224) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.simp.SimpMessagingTemplate.convertAndSendToUser(SimpMessagingTemplate.java:208) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
   [  .... application frames ..... ] 
Caused by: java.util.ConcurrentModificationException: null
        at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:966) ~[na:1.8.0_45]
        at java.util.LinkedList$ListItr.next(LinkedList.java:888) ~[na:1.8.0_45]
        at org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler.sendMessageToSubscribers(SimpleBrokerMessageHandler.java:201) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler.handleMessageInternal(SimpleBrokerMessageHandler.java:149) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.simp.broker.AbstractBrokerMessageHandler.handleMessage(AbstractBrokerMessageHandler.java:238) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:135) ~[spring-messaging-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        ... 73 common frames omitted

Affects: 4.1.6

Issue Links:

  • #17264 ConcurrentModificationException in SimpleBrokerMessageHandler
  • #17482 Support 'selector' header for subscriptions with SimpleBrokerMessageHandler
  • #17793 LinkedMultiValueMap should allow for deep copy of List values
  • #17797 NullPointerException in DefaultSubscriptionRegistry.removeSubscription
  • #21789 UriComponentsBuilder.uriComponents doesn't properly clone unmodifiable queryParams

Referenced from: commits ca9beea, 16cbfcf, f0175bc

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 2, 2015

Juergen Hoeller commented

It looks like this should have been fixed with #17264 as of 4.1.5 already...

Juergen

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 2, 2015

Rossen Stoyanchev commented

Yes the fix for SPR-12665 was meant to ensure that the MultiValueMap instances in the accessCache never change. However it looks like the copy constructor of LinkedMultiValueMap does not do a deep copy of the List for each value. This is a surprise since LinkedMultiValueMap is aware of the List values and there is an argument to be made for fixing it there. Either way we need to ensure the MultiValueMap in the accessCache is independent of that in the updateCache.

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 6, 2015

Juergen Hoeller commented

Indeed, it looks like @LinkedMultiValueMap should really be doing a deep copy of its List values there.

Juergen

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 6, 2015

Rossen Stoyanchev commented

I've added a test that demonstrates this issue does not affect 4.2. The same test fails in 4.1.x with a ConcurrentModificationException. The reason for the difference is the following commit b6327a that expanded subscription support for 4.2 (adding a 'selector' expression-based header) and in the process changed subscriptions from being stored in HashSet to CopyOnWriteArraySet.

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 6, 2015

Rossen Stoyanchev commented

Never mind my last comment. I added the wrong test. The issue affects 4.2 just the same.

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 6, 2015

Juergen Hoeller commented

Fixed in 4.2 through using LinkedMultiValueMap's new deepCopy() mechanism.

4.1.8 backport following based on local deep copies within DefaultSubscriptionRegistry, plus the CopyOnWriteArraySet part from #17482.

Juergen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.