Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-1776] Intermittent ConcurrentModificationException on Android

GitHub Issuen/a
TypeBug
PriorityMedium
StatusClosed
ResolutionInvalid
Resolution Date2012-08-20T16:19:25.000+0000
Affected Version/sn/a
Fix Version/sn/a
ComponentsAndroid
Labelsandroid, concurrentmodificationexception, context, crash, exception, hashmap, synchronization, threading
ReporterBrion Vibber
AssigneeNeeraj Gupta
Created2011-04-15T03:01:58.000+0000
Updated2017-03-09T23:35:07.000+0000

Description

In StatusNet Mobile we've been working with a lot of event listeners, including Ti.App listeners for communication between our primary context, another context to run XML parsing in the background, and a WebView used for various data display.

Sometimes we end up with cases where things quite reliably crash the VM dumping a raw C-level stacktrace that can be worked around temporarily by shuffling when/where we do an addEventListener, but I'm also seeing more intermittent bugs where I get a Java-level backtrace like this:

W/dalvikvm( 1759): threadid=1: thread exiting with uncaught exception (group=0x4001d7f0)
E/TiUncaughtHandler( 1759): (main) [43,123166] Sending event: exception on thread: main msg:java.lang.RuntimeException: Unable to destroy activity {net.status.client.mobile/org.appcelerator.titanium.TiActivity}: java.util.ConcurrentModificationException
E/TiUncaughtHandler( 1759): java.lang.RuntimeException: Unable to destroy activity {net.status.client.mobile/org.appcelerator.titanium.TiActivity}: java.util.ConcurrentModificationException
E/TiUncaughtHandler( 1759):     at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3655)
E/TiUncaughtHandler( 1759):     at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3673)
E/TiUncaughtHandler( 1759):     at android.app.ActivityThread.access$2900(ActivityThread.java:125)
E/TiUncaughtHandler( 1759):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
E/TiUncaughtHandler( 1759):     at android.os.Handler.dispatchMessage(Handler.java:99)
E/TiUncaughtHandler( 1759):     at android.os.Looper.loop(Looper.java:123)
E/TiUncaughtHandler( 1759):     at android.app.ActivityThread.main(ActivityThread.java:4627)
E/TiUncaughtHandler( 1759):     at java.lang.reflect.Method.invokeNative(Native Method)
E/TiUncaughtHandler( 1759):     at java.lang.reflect.Method.invoke(Method.java:521)
E/TiUncaughtHandler( 1759):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
E/TiUncaughtHandler( 1759):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
E/TiUncaughtHandler( 1759):     at dalvik.system.NativeStart.main(Native Method)
E/TiUncaughtHandler( 1759): Caused by: java.util.ConcurrentModificationException
E/TiUncaughtHandler( 1759):     at java.util.HashMap$HashIterator.nextEntry(HashMap.java:795)
E/TiUncaughtHandler( 1759):     at java.util.HashMap$KeyIterator.next(HashMap.java:822)
E/TiUncaughtHandler( 1759):     at org.appcelerator.titanium.TiContext.removeEventListenersFromContext(TiContext.java:468)
E/TiUncaughtHandler( 1759):     at org.appcelerator.titanium.TiProxy.removeEventListenersFromContext(TiProxy.java:242)
E/TiUncaughtHandler( 1759):     at org.appcelerator.titanium.TiApplication.removeEventListenersFromContext(TiApplication.java:275)
E/TiUncaughtHandler( 1759):     at org.appcelerator.titanium.TiContext.release(TiContext.java:879)
E/TiUncaughtHandler( 1759):     at org.appcelerator.titanium.TiActivity.onDestroy(TiActivity.java:415)
E/TiUncaughtHandler( 1759):     at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3642)
E/TiUncaughtHandler( 1759):     ... 11 more

It looks like there's a lot of unsynchronized access to the event listener hashmaps in TiContext; there's a few synchronized(eventListeners){...} constructs but they're not consistent, and I'm not too sure what does what.

Comments

  1. Brion Vibber 2011-04-15

    I don't have a minimal test case yet, but I was able to decrease incidence by switching order of some operations so that a window is closed after, instead of before, starting some background operations for account switching.

    Looks like the cleanup of listeners when closing out the window's activity was conflicting with something else that was getting run...

  2. Junaid Younus 2012-08-20

    No test case, ticket marked as invalid.
  3. Neeraj Gupta 2012-08-20

    Please reopen this ticket if you can provide a test case or better description to reproduce this issue.
  4. Lee Morris 2017-03-09

    Closing ticket as invalid.

JSON Source