Details
Description
I don't know if it happens all the time, but I've encountered a situation where I executed Distribution Wizard in a non interactive fashion, and it simply failed with the following stacktrace:
Caused by: java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode(HashMap.java:1445) at java.util.HashMap$KeyIterator.next(HashMap.java:1469) at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1044) at org.xwiki.extension.distribution.internal.job.step.OutdatedExtensionsDistributionStep.executeNonInteractive(OutdatedExtensionsDistributionStep.java:139) at org.xwiki.extension.distribution.internal.job.AbstractDistributionJob.runInternal(AbstractDistributionJob.java:222) at org.xwiki.job.AbstractJob.runInContext(AbstractJob.java:242) at org.xwiki.job.AbstractJob.run(AbstractJob.java:219) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ... 1 more
A collection is iterated with a foreach loop, but then the repair() method updates the collection, which means the collection changes while being iterated. Basic ConcurrentModificationException.
A solution could be to make sure DefaultInstalledExtension#getNamespaces() returns a copy of the collection (which is supposed to be an UnmodifiableSet BTW), or manually creates a copy in OutdatedExtensionsDistributionStep. But the whole thing is actually weird.