Ticket #39 (closed defect: fixed)

Opened 19 months ago

Last modified 14 months ago

ConcurrentModificationException in DefaultWaitEventManager without XP threadpool

Reported by: T.Doenz Owned by: T.Doenz
Priority: major Milestone: 2.0
Component: Runtime Version: 2.0
Keywords: Cc:

Description

When the Core Processor (XP) is configured to not use a thread pool ("0" threads in the config) a java.util.ConcurrentModificationException can occur. This is reproducible for me with Michael Zehender's PingPong application when InMemoryRunnerMain is executed and the core is configured in InMemoryRunner with:

Configuration config = new Configuration();
config.setXpThreadNumber(0);
core = DefaultMzsCore.newInstance(config);

Change History

comment:1 Changed 19 months ago by T.Doenz

I do not know why a ConcurrentModificationException can occur there, all public methods of DefaultWaitAndEventManager are synchronized.

An example stack trace for this bug is

20:53:40.656 [main] ERROR o.m.runtime.tasks.AbstractTask - Non-MS Exception during task execution
java.util.ConcurrentModificationException: null
	at java.util.AbstractList$Itr.checkForComodification(Unknown Source) ~[na:1.6.0_22]
	at java.util.AbstractList$Itr.next(Unknown Source) ~[na:1.6.0_22]
	at org.mozartspaces.runtime.blocking.DefaultWaitAndEventManager.rescheduleAndRemoveAllTasks(DefaultWaitAndEventManager.java:216) ~[mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.runtime.blocking.DefaultWaitAndEventManager.finishTransaction(DefaultWaitAndEventManager.java:206) ~[mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.runtime.blocking.DefaultWaitAndEventManager.processTransactionCommit(DefaultWaitAndEventManager.java:166) ~[mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.runtime.DefaultTransactionManager.commitTx(DefaultTransactionManager.java:219) ~[mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.runtime.DefaultTransactionManager.commitTransaction(DefaultTransactionManager.java:136) ~[mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.runtime.tasks.CommitTransactionTask.runSpecific(CommitTransactionTask.java:76) ~[mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.runtime.tasks.CommitTransactionTask.runSpecific(CommitTransactionTask.java:29) ~[mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.runtime.tasks.AbstractTask.processRequest(AbstractTask.java:238) [mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.runtime.tasks.AbstractTask.run(AbstractTask.java:96) [mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.core.util.WithinThreadExecutorService.execute(WithinThreadExecutorService.java:33) [mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.runtime.ThreadPoolRequestHandler.processRequest(ThreadPoolRequestHandler.java:97) [mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.core.DefaultMzsCore.routeRequestToDestinationSpace(DefaultMzsCore.java:228) [mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.core.DefaultMzsCore.send(DefaultMzsCore.java:143) [mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.core.DefaultMzsCore.send(DefaultMzsCore.java:126) [mozartspaces-runtime-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.core.Capi.sendRequestAndWaitForResult(Capi.java:1072) [mozartspaces-core-api-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.core.Capi.commitTransaction(Capi.java:785) [mozartspaces-core-api-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at org.mozartspaces.core.Capi.commitTransaction(Capi.java:767) [mozartspaces-core-api-2.0-SNAPSHOT.jar:2.0-SNAPSHOT]
	at idealspace.tests.pingpong.proxy.AbstractProxy.send(AbstractProxy.java:59) [classes/:na]
	at idealspace.tests.pingpong.proxy.PingProxy.ping(PingProxy.java:43) [classes/:na]
	at idealspace.tests.pingpong.PingControl.circle(PingControl.java:46) [classes/:na]
	at idealspace.tests.pingpong.InMemoryRunner.once(InMemoryRunner.java:63) [classes/:na]
	at idealspace.tests.pingpong.InMemoryRunnerMain.main(InMemoryRunnerMain.java:46) [test-classes/:na]

comment:2 Changed 19 months ago by M.Zehender

I didn't look at the code, however the ConcurrentModificationException can be thrown if you modify the collection while iterating over it. This implies that synchronizing methods don't prevent the ConcurrentModificationException.

An excerpt from the API: if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.

comment:3 Changed 19 months ago by T.Doenz

I am aware of that, but I am not modifying the collection while I am iterating over it, not even through the iterator. The exception is thrown in the following code (in line 216 is the "for"):

    private void rescheduleAndRemoveAllTasks(final List<Task> tasks) {
        for (Task task : tasks) {
            rescheduleTask(task);
        }
        tasks.clear();
    }

comment:4 Changed 19 months ago by T.Doenz

The problem is most probably that the rescheduled task is immediately executed (synchronously, in the same thread), should be delayed and is thus added to the very same list instance (via the addTask method), which triggers the exception when the iteration continues. Synchronizing does not help here, because everything runs in the same thread and Java monitors are reentrant. Thanks for the hint, Michael.

comment:5 Changed 18 months ago by T.Doenz

  • Priority changed from minor to major
  • Status changed from new to assigned

comment:6 Changed 18 months ago by T.Doenz

  • Milestone set to 2.0

comment:7 Changed 17 months ago by T.Doenz

A test case showing this bug is in the class Ticket39ConcurrentModificationExceptionInDefaultWaitEventManager(module core-integration-test).

comment:8 Changed 17 months ago by T.Doenz

  • Status changed from assigned to closed
  • Resolution set to fixed

tasks are now rescheduled asynchronously, if no XP thread pool is used fixed with SVN rev. 10025

comment:9 Changed 14 months ago by amog2011

I am aware of that, but I am not modifying the collection while I am iterating over it, not even through the iterator.

air jordan
Note: See TracTickets for help on using tickets.