If a bean attempted to create a new timer at the same time as another thread was calling the `getTimers()` method, a `ConcurrentModificationException` was thrown. This occurred because the `getTimers()` method did not call `synchronized()` on the timers.
This issue is fixed in this release, and the timer service implementation's `getTimers()` method now properly calls `synchronized()` on the timers.
Created attachment 810437 [details]
The implementation of org.jboss.as.ejb3.timerservice.TimerService.getTimers() iterates over three collections (activePersistentTimers, persistentWaitingOnTxCompletionTimers, nonPersistentTimers) using a for-each loop without synchronizing on them.
This can lead to a ConcurrentModificationException if a bean is creating a timer and at the same time another thread is calling getTimers().
Reproducer mimicking this scenario is attached. Just deploy it to a running EAP instance. A Singleton bean will create/remove lots of timers and at the same time another thread will call getTimers repeatedly.
Expected outcome: it deploys successfully and says "No ConcurrentModificationException encountered"
Actual outcome - after some time:
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:894) [rt.jar:1.7.0_25]
at java.util.HashMap$ValueIterator.next(HashMap.java:922) [rt.jar:1.7.0_25]
at TimerGenerator.getTimers(TimerGenerator.java:63) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_25]
Assigning firstname.lastname@example.org EJB issues to email@example.com. Please re-assign to Cheng or others as needed.
Going to fix this myself.
Can't reproduce on upstream, it seems it was fixed there earlier with commit 7a4541f6.
The pull request looks OK so I'm devel_ack+ this.
Fixed in 6.3.0.DR0.