Details
-
Bug
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
6.15.0
Description
ConcurrentModificationException may occur when calling EventBus.post() because subscriptionsForPage collection can be modified by another thread during a loop inside AtmosphereRequestHandler.executeHandlers:
java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429) at java.util.HashMap$KeyIterator.next(HashMap.java:1453) at com.google.common.collect.AbstractMultimap$WrappedCollection$WrappedIterator.next(AbstractMultimap.java:540) at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1102) at com.google.common.collect.Iterators$8.computeNext(Iterators.java:735) at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143) at com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138) at org.apache.wicket.atmosphere.AtmosphereRequestHandler.executeHandlers(AtmosphereRequestHandler.java:79) at org.apache.wicket.atmosphere.AtmosphereRequestHandler.respond(AtmosphereRequestHandler.java:74) at org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.respond(RequestCycle.java:862) at org.apache.wicket.request.RequestHandlerStack.execute(RequestHandlerStack.java:64) at org.apache.wicket.request.cycle.RequestCycle.execute(RequestCycle.java:261) at org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:218) at org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:289) at org.apache.wicket.atmosphere.EventBus.post(EventBus.java:417) at org.apache.wicket.atmosphere.EventBus.postToSingleResource(EventBus.java:393) at org.apache.wicket.atmosphere.EventBus.post(EventBus.java:346) at org.apache.wicket.atmosphere.EventBus.post(EventBus.java:329)
I think the problem is inside in EventBus.postToSingleResource() method:
subscriptionsForPage = Collections2.filter( Collections.unmodifiableCollection(subscriptions.get(key)), new EventFilter(event));
I think collection get from "subscriptions.get(key)" should be copied first and then assigned to subscriptionsForPage variable. Now it is a pass as a reference (not directly but it is) and it can lead to ConcurrentModificationException.
It is not easy to reproduce this problem (more that one thread must call post at the same time), but sometimes it happen.