Skip to content

Commit

Permalink
Prevent ConcurrentModificationException in PomInstallableUnitStore
Browse files Browse the repository at this point in the history
In some rare cases it is possible that a ConcurrentModificationException
occurs in the PomInstallableUnitStore when projects are build in
parallel and as part of this artifacts are attached.

This adds a new safeCopy method to retry the copy operation in such case
and checks for possible null values because of concurrent removals.

(cherry picked from commit 27398a5)
  • Loading branch information
laeubi authored and eclipse-tycho-bot committed Mar 22, 2024
1 parent d0f217f commit 8fa411b
Showing 1 changed file with 24 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
Expand Down Expand Up @@ -221,13 +223,34 @@ private Stream<Artifact> getArtifactStream(Artifact artifact, IArtifactFacade fa
MavenProject mavenProject = projectFacade.getReactorProject().adapt(MavenProject.class);
if (mavenProject != null) {
return Stream.concat(Stream.of(mavenProject.getArtifact()),
mavenProject.getAttachedArtifacts().stream());
safeCopy(mavenProject.getAttachedArtifacts()).stream());
}
}
return Stream.of(artifact);

}

private List<Artifact> safeCopy(List<Artifact> list) {
while (true) {
//in parallel execution mode it is possible that items are added to the attached artifacts what will throw ConcurrentModificationException so we must make a quite unusual copy here
//we can not only use one of the List.copyOf(), ArrayList(...) and so on e.g. they often just copy the data but a concurrent copy can lead to data corruption or null values
try {
List<Artifact> copyList = new ArrayList<>();
for (Iterator<Artifact> iterator = list.iterator(); iterator.hasNext();) {
Artifact a = iterator.next();
if (a != null) {
copyList.add(a);
}
}
return copyList;
} catch (ConcurrentModificationException e) {
//retry...
Thread.yield();
}
}

}

void addPomDependencyConsumer(Consumer<PomDependency> consumer) {
gatheredDependencies.forEach(consumer);
dependencyConsumer.add(consumer);
Expand Down

0 comments on commit 8fa411b

Please sign in to comment.