Skip to content

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

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

Closed
spring-projects-issues opened this issue Jul 2, 2015 · 6 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues 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:

Referenced from: commits ca9beea, 16cbfcf, f0175bc

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues 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-projects-issues
Copy link
Collaborator Author

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-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

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

Juergen

@spring-projects-issues
Copy link
Collaborator Author

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-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

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

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues 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
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants