Skip to content

Commit 5b04c7c

Browse files
committed
Make a synchronized copy of availableKeys
`synchronizedSet(s)` ends up making a new wrapper for the supplied set, which means on subsequent calls, it becomes a SynchronizedSet, wrapped in a SynchronizedSet, wrapped ... etc. When using the LocalDataStore, the ParseObject.State is reused for every matching ClassName+ObjectId pair, so every time a ParseObject is parsed from JSON data, the existing object is "refreshed" by making a copy of its State, and then merging with the new data. Every call to State.newBuilder() is therefore adding a new layer of SynchronizedSet to the availableKeys Set. Eventually that nested hierarchy of sets becomes so large that it causes a StackOverflowError for any operation on the collection. By making a copy of the set before wrapping it in synchronizedSet(), that nested hierarchy becomes severed, and we end up with just one level of wrappers.
1 parent 5d480c8 commit 5b04c7c

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

parse/src/main/java/com/parse/ParseObject.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4076,7 +4076,7 @@ public Init(String className) {
40764076
objectId = state.objectId();
40774077
createdAt = state.createdAt();
40784078
updatedAt = state.updatedAt();
4079-
availableKeys = Collections.synchronizedSet(state.availableKeys());
4079+
availableKeys = Collections.synchronizedSet(new HashSet<>(state.availableKeys()));
40804080
for (String key : state.keySet()) {
40814081
serverData.put(key, state.get(key));
40824082
availableKeys.add(key);

0 commit comments

Comments
 (0)