United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6636331 ConcurrentModificationException in AppContext code
JDK-6636331 : ConcurrentModificationException in AppContext code

Details
Type:
Bug
Submit Date:
2007-12-01
Status:
Closed
Updated Date:
2011-05-18
Project Name:
JDK
Resolved Date:
2011-05-18
Component:
client-libs
OS:
windows_vista,generic
Sub-Component:
java.awt
CPU:
x86,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
6u10,7
Fixed Versions:

Related Reports
Backport:
Backport:
Duplicate:

Sub Tasks

Description
the following problem has been reported by ###@###.###

I happened to find this exception in one of our nightly testing logs. Is this a known issue? It looks like a lack of synchronization in AppContext.getAppContexts().

Exception in thread "Thread-2" java.lang.ExceptionInInitializerError
    at com.sun.deploy.util.DeployUIManager.setLookAndFeel(Unknown Source)
    at sun.plugin.util.PluginSysUtil$1.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.util.ConcurrentModificationException
    at java.util.IdentityHashMap$IdentityHashMapIterator.nextIndex(Unknown Source)
    at java.util.IdentityHashMap$ValueIterator.next(Unknown Source)
    at java.util.AbstractCollection.addAll(Unknown Source)
    at java.util.HashSet.<init>(Unknown Source)
    at sun.awt.AppContext.getAppContexts(Unknown Source)
    at java.awt.Toolkit$DesktopPropertyChangeSupport.firePropertyChange(Unknown Source)
    at java.beans.PropertyChangeSupport.firePropertyChange(Unknown Source)
    at java.awt.Toolkit.setDesktopProperty(Unknown Source)
    at sun.awt.windows.WToolkit.updateProperties(Unknown Source)
    at sun.awt.windows.WToolkit.lazilyInitWProps(Unknown Source)
    at sun.awt.windows.WToolkit.lazilyLoadDesktopProperty(Unknown Source)
    at java.awt.Toolkit.getDesktopProperty(Unknown Source)
    at javax.swing.UIManager.<clinit>(Unknown Source)
    ... 3 more

                                    

Comments
EVALUATION

It looks like the problem is in AppContext.getAppContexts()
    public static Set<AppContext> getAppContexts() {
        return new HashSet<AppContext>(threadGroup2appContext.values());
    }

we should clone threadGroup2appContext before getting values.
The problem was introduced by the fix for 6536220.
                                     
2007-12-01
EVALUATION

Well, we can not just use clone() since threadGroup2appContext is a Map which doesn't have
clone() method.  Also we can not use IdentityHashMap as type for threadGroup2appContext since 
we need to have synchronized map, but Collections.synchronizedMap() returns just Map.

It looks like to fix the problem we should create some special class which will provide Map
interface (well not complete interface, just methods we need) and method clone().
                                     
2007-12-01
EVALUATION

actually there is very simple fix.  a map Collections.synchronizedMap() returns uses this for
synchronization (it is part of contract of this method)  So we just need to use the same
syncronization in our code

public static Set<AppContext> getAppContexts() {
    synchronized (threadGroup2appContext) {
        return new HashSet<AppContext>(threadGroup2appContext.values());
    }
}
                                     
2007-12-01
SUGGESTED FIX

--- a/src/share/classes/sun/awt/AppContext.java	Sat Dec 15 08:25:38 2007 +0300
+++ b/src/share/classes/sun/awt/AppContext.java	Sat Dec 15 08:26:12 2007 +0300
@@ -146,7 +146,9 @@ public final class AppContext {
      * Returns a set containing all <code>AppContext</code>s.
      */
     public static Set<AppContext> getAppContexts() {
-        return new HashSet<AppContext>(threadGroup2appContext.values());
+        synchronized (threadGroup2appContext) {
+            return new HashSet<AppContext>(threadGroup2appContext.values());
+        }
     }
 
     /* The main "system" AppContext, used by everything not otherwise
                                     
2008-03-13



Hardware and Software, Engineered to Work Together