HashSet throwing incorrect exception & possible compiler bug

1 view
Skip to first unread message

Vitali Lovich

unread,
Mar 18, 2009, 5:57:10 PM3/18/09
to Google-Web-Tool...@googlegroups.com
First major concern is that I got a ConcurrentModificationException when iterating over a HashSet - this exception is completely meaningless in the context of the browser (no threading).  There's also not really any meaningful message in the stack trace:

00:20:24.446 [ERROR] Uncaught exception escaped java.util.ConcurrentModificationException: null at java.util.HashMap$HashIterator.nextEntry(HashMap.java:810) at java.util.HashMap$KeyIterator.next(HashMap.java:845)

The relevant code that causes this is:

  private HashMap<ModelAction, HashSet<ModelListener>> models;
// .....
  HashSet<ModelListener> listeners = models.get(action);
    if (listeners != null) {
      for (ModelListener listener : listeners)
        listener.modelUpdated(action, info);
    }

Replacing it with a regular iterator:

      Iterator<ModelListener> iterator = listeners.iterator();
      while (iterator.hasNext())
          iterator.next().modelUpdated(action, info);

somehow fixes the problem.  Is the compiler screwing up in converting the Java for-each notation into the iterator equivalent, or am I missing something?

Some background:  this succeeds the first time it is called from within an event handler context (to notify the model to perform a login attempt).  However, it fails the second time it is called when it is called from an AsyncCallback context (returning the result that it was a successful login).  However, at no point is the HashSet used modified (after startup where it contains currently 1 element).

Thanks

Ray Cromwell

unread,
Mar 18, 2009, 6:10:28 PM3/18/09
to Google-Web-Tool...@googlegroups.com
On Wed, Mar 18, 2009 at 2:57 PM, Vitali Lovich <vlo...@gmail.com> wrote:
First major concern is that I got a ConcurrentModificationException when iterating over a HashSet - this exception is completely meaningless in the context of the browser (no threading).  There's also not really any meaningful message in the stack trace:

It applies equally well to single-thread scenarios, see the JavaDoc: http://java.sun.com/j2se/1.5.0/docs/api/java/util/ConcurrentModificationException.html
 
somehow fixes the problem.  Is the compiler screwing up in converting the Java for-each notation into the iterator equivalent, or am I missing something?

Some background:  this succeeds the first time it is called from within an event handler context (to notify the model to perform a login attempt).  However, it fails the second time it is called when it is called from an AsyncCallback context (returning the result that it was a successful login).  However, at no point is the HashSet used modified (after startup where it contains currently 1 element).

It's possible there's a bug, but perhaps you should try wrapping things in Collections.unmodifableSet()/Map() to make sure it's not being modified in some way.
 
-Ray

Vitali Lovich

unread,
Mar 18, 2009, 6:31:06 PM3/18/09
to Google-Web-Tool...@googlegroups.com
On Wed, Mar 18, 2009 at 6:10 PM, Ray Cromwell <cromw...@gmail.com> wrote:


On Wed, Mar 18, 2009 at 2:57 PM, Vitali Lovich <vlo...@gmail.com> wrote:
First major concern is that I got a ConcurrentModificationException when iterating over a HashSet - this exception is completely meaningless in the context of the browser (no threading).  There's also not really any meaningful message in the stack trace:

It applies equally well to single-thread scenarios, see the JavaDoc: http://java.sun.com/j2se/1.5.0/docs/api/java/util/ConcurrentModificationException.html
Right - I was just implying that seeing as how my code in no way actually modifies the set while iterating over it, the concurrent modification exception is meaningless.

 
somehow fixes the problem.  Is the compiler screwing up in converting the Java for-each notation into the iterator equivalent, or am I missing something?

Some background:  this succeeds the first time it is called from within an event handler context (to notify the model to perform a login attempt).  However, it fails the second time it is called when it is called from an AsyncCallback context (returning the result that it was a successful login).  However, at no point is the HashSet used modified (after startup where it contains currently 1 element).

It's possible there's a bug, but perhaps you should try wrapping things in Collections.unmodifableSet()/Map() to make sure it's not being modified in some way.
Nope - still throws an exception.  Nothing in the code example above modifies the hashset (I print a message when I register a listener, and I'm not getting that) - I'm going to verify this though (step through the first successful call)

 
-Ray




Ray Cromwell

unread,
Mar 18, 2009, 6:43:50 PM3/18/09
to Google-Web-Tool...@googlegroups.com
On Wed, Mar 18, 2009 at 3:31 PM, Vitali Lovich <vlo...@gmail.com> wrote:

Nope - still throws an exception.  Nothing in the code example above modifies the hashset (I print a message when I register a listener, and I'm not getting that) - I'm going to verify this though (step through the first successful call)

Is this happening in web mode, hosted mode, or both? Does it happen in hosted mode?

-Ray

 


 
-Ray







Vitali Lovich

unread,
Mar 18, 2009, 6:53:45 PM3/18/09
to Google-Web-Tool...@googlegroups.com
Sorry - it was my fault.  I tracked it down.  Within the listener, I was unregistering it - stupid me.

Thanks for your help
Vitali

Ray Ryan

unread,
Mar 18, 2009, 7:18:06 PM3/18/09
to Google-Web-Tool...@googlegroups.com
FWIW, the HandlerManager class introduced in 1.6 allows concurrent
mods. Because really you're not so silly to want to do that.

rjrjr

Vitali Lovich

unread,
Mar 18, 2009, 10:08:35 PM3/18/09
to Google-Web-Tool...@googlegroups.com
It's actually not event listeners - it's just a simple messaging delivery system I wrote.  I was more referring to me being stupid & not stepping remembering that I had modified the map.  I just saw ConcurrentModificationException, no obvious modification of the map within the iteration, and just got confused about what's going on.

Scott Blum

unread,
Mar 19, 2009, 10:17:22 AM3/19/09
to Google-Web-Tool...@googlegroups.com
By the way, GWT doesn't actually throw CoMods in web mode.  So that's the real JRE you were tangling with. :-)

Vitali Lovich

unread,
Mar 19, 2009, 11:46:35 AM3/19/09
to Google-Web-Tool...@googlegroups.com
Thanks.  Makes sense because when I tried looking it up in the GWT HashMap implementation, I couldn't find it :D.
Reply all
Reply to author
Forward
0 new messages