Skip to content

ConcurrentModificationException in ParseTraverser #1061

Closed
@shlusiak

Description

@shlusiak

There is still the occasional ConcurrentModificationException in ParseTraverser.

Parse version: 1.25.0

Stack trace:

Fatal Exception: java.util.ConcurrentModificationException
       at java.util.HashMap$HashIterator.nextNode(HashMap.java:1441)
       at java.util.HashMap$KeyIterator.next(HashMap.java:1465)
       at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1084)
       at com.parse.ParseTraverser.traverseInternal(ParseTraverser.java:101)
       at com.parse.ParseTraverser.traverseInternal(ParseTraverser.java:95)
       at com.parse.ParseTraverser.traverseInternal(ParseTraverser.java:102)
       at com.parse.ParseTraverser.traverse(ParseTraverser.java:140)
       at com.parse.OfflineStore.saveLocallyAsync(OfflineStore.java:666)
       at com.parse.OfflineStore.access$1300(OfflineStore.java:36)

The issue appears that while ParseObject.keySet() returns a Collections.unmodifiableSet(), the set is a read-through to the underlying HashMap, which is not synchronised.

/**
* Returns a set view of the keys contained in this object. This does not include createdAt,
* updatedAt, authData, or objectId. It does include things like username and ACL.
*/
public Set<String> keySet() {
synchronized (mutex) {
return Collections.unmodifiableSet(estimatedData.keySet());
}
}

I believe we either need to make the estimatedData a synchronised Map, or we need to work on a copy of the set when traversing, to guard against concurrent modifications. Thoughts about making estimatedData a synchronized map?

} else if (root instanceof ParseObject) {
if (traverseParseObjects) {
ParseObject object = (ParseObject) root;
for (String key : object.keySet()) {
traverseInternal(object.get(key), true, seen);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    type:bugImpaired feature or lacking behavior that is likely assumed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions