Bug 794790 - add code that protects against ConcurrentModificationExceptions to any places in the plugin container where we iterate a Resource's child Resources
add code that protects against ConcurrentModificationExceptions to any places...
Status: CLOSED CURRENTRELEASE
Product: RHQ Project
Classification: Other
Component: Plugin Container (Show other bugs)
4.2
Unspecified Unspecified
unspecified Severity medium (vote)
: ---
: RHQ 4.3.0
Assigned To: Charles Crouch
Mike Foley
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2012-02-17 11:37 EST by Ian Springer
Modified: 2015-02-01 18:27 EST (History)
4 users (show)

See Also:
Fixed In Version: 4.3
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2013-09-01 06:17:08 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:


Attachments (Terms of Use)

  None (edit)
Description Ian Springer 2012-02-17 11:37:01 EST

    
Comment 1 Ian Springer 2012-02-17 11:40:22 EST
Here's an example of how to guard against

  // Copy child Resources to an array and iterate that, 
  // rather than iterating the Set, which could cause
  // a ConcurrentModificationException if another thread
  // tries to modify the Set while we're iterating it.
  Resource[] childResources = resource.getChildResources().toArray(
     new Resource[resource.getChildResources().size()]);
  for (Resource childResource : childResources) {
     // do something w/ child Resource
  }

To find all the places that may need fixing, do a find usages of Resource.getChildResources().
Comment 2 Charles Crouch 2012-02-17 12:33:20 EST
Are we sure that copying the set into an array is the best solution?
Have we thought about doing something like this in org.rhq.core.domain.resource.Resource:


private Set<Resource> childResources = Collections.newSetFromMap(
     new ConcurrentHashMap<Resource, Boolean>());

versus what we have now:

private Set<Resource> childResources = new LinkedHashSet<Resource>();

How critical is the *Linked* part of LinkedHastSet, i.e. that we need to iterate over the set in some defined order (insertion-order)? If its critical then maybe we could look at:

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CopyOnWriteArraySet.html

Noting: "[CopyOnWriteArraySet] is best suited for applications in which set sizes generally stay small, read-only operations vastly outnumber mutative operations, and you need to prevent interference among threads during traversal."

It looks like this would have to change too:
  public void setChildResources(Set<Resource> children) {
         if (children == null) {
             children = new LinkedHashSet<Resource>();
         }
         this.childResources = children;
     }

Given we currently allow people to supply their own Set implementation through setChildResources I presume we can't be relying on the fact we'll always have a LinkedHashSet.
Comment 3 Ian Springer 2012-02-20 13:08:46 EST
Good idea. 

Done in master: http://git.fedorahosted.org/git/?p=rhq/rhq.git;a=commitdiff;h=6f7913a
Comment 4 Mike Foley 2012-02-29 18:22:41 EST
this fix caused this regression 

https://bugzilla.redhat.com/show_bug.cgi?id=797999
Comment 5 John Mazzitelli 2012-03-26 11:54:33 EDT
I think this issue is not fixed - see code analysis in bug #801432
Comment 8 Heiko W. Rupp 2013-09-01 06:17:08 EDT
Bulk closing of items that are on_qa and in old RHQ releases, which are out for a long time and where the issue has not been re-opened since.

Note You need to log in before you can comment on or make changes to this bug.