diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/PomInstallableUnitStore.java b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/PomInstallableUnitStore.java index 833f07ce0c..b7424c2902 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/PomInstallableUnitStore.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/PomInstallableUnitStore.java @@ -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; @@ -221,13 +223,34 @@ private Stream 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 safeCopy(List 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 copyList = new ArrayList<>(); + for (Iterator 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 consumer) { gatheredDependencies.forEach(consumer); dependencyConsumer.add(consumer);