Details
-
Bug
-
Resolution: Fixed
-
Neutral
-
6.2.26
-
None
-
None
Description
A ConcurrentModificationException can sometimes occur when trying to add read permissions in the MagnoliaAccessProvider.
Reproduce
Have multiple threads try to add read permissions at the same time.
Expected
Permissions list should be thread safe.
Actual
2022-03-21T21:08:22,967 ERROR org.apache.jackrabbit.core.DefaultSecurityManager : Failed to instantiate AccessManager (org.apache.jackrabbit.core.security.DefaultAccessManager) java.util.ConcurrentModificationException: null at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1363) ~[?:1.8.0_312] at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126) ~[?:1.8.0_312] at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:499) ~[?:1.8.0_312] at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:486) ~[?:1.8.0_312] at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[?:1.8.0_312] at java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:230) ~[?:1.8.0_312] at java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:196) ~[?:1.8.0_312] at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:1.8.0_312] at java.util.stream.ReferencePipeline.anyMatch(ReferencePipeline.java:516) ~[?:1.8.0_312] at info.magnolia.cms.core.MagnoliaAccessProvider.addReadPermission(MagnoliaAccessProvider.java:202) ~[magnolia-core-6.2.16.jar:?] at info.magnolia.cms.core.MagnoliaAccessProvider.addJcrSystemReadPermissions(MagnoliaAccessProvider.java:197) ~[magnolia-core-6.2.16.jar:?] at info.magnolia.cms.core.MagnoliaAccessProvider.compilePermissions(MagnoliaAccessProvider.java:107) ~[magnolia-core-6.2.16.jar:?]
Development notes
Either the method needs to be synchronized or the permissions list needs to be.
java.util.concurrent. CopyOnWriteArrayList see https://stackoverflow.com/questions/11360401/java-synchronized-list
or Collections.synchronizedList(arraylist);
Chosen CopyOnWriteArrayList because or requirement for Collections.synchronizedList usage:
...it is critical that all access to the backing list is accomplished through the returned list.
It is imperative that the user manually synchronize on the returned list when traversing it via Iterator, Spliterator or Stream:...