Skip to content

MavenProject.getArtifacts() publishes a half-built set under concurrent access #13200

Closed

Description

@slachiewicz

Affected version

3.9.x and master (same code on both).

Bug description

MavenProject.getArtifacts() initialises its set lazily and assigns the field before filling it:

artifacts = new LinkedHashSet<>(resolvedArtifacts.size() * 2);
for (Artifact artifact : resolvedArtifacts) {
    if (artifactFilter.include(artifact)) {
        artifacts.add(artifact);
    }
}

(maven-3.9.x MavenProject.java:675, master MavenProject.java:897)

A second thread calling getArtifacts() during the loop receives the half-built set and any iteration over it throws ConcurrentModificationException while the first thread keeps adding. The MojoExecutor project and aggregator locks keep mojo executions apart, so in a plain build the two callers should not overlap; the trace in apache/maven-plugin-tools#852 (maven-plugin-plugin:descriptor on a parallel build, LinkedHashMap$LinkedHashIterator.nextNode under JavaAnnotationsMojoDescriptorExtractor.extendJavaProjectBuilder) shows that something does overlap. The trigger there is not identified; the publication itself is unsafe regardless.

Fill a local set and assign it once, so a concurrent reader sees either null handling or a complete set:

Set<Artifact> result = new LinkedHashSet<>(...);
for (...) { ... result.add(artifact); }
artifacts = result;

The same pattern exists in getArtifactMap() / getDependencyArtifacts() and is worth the same treatment.

Activity

  1. added a commit that references this issue on Sep 19, 2026
    ab67bf7
  2. added 2 commits that reference this issue on Sep 19, 2026
    7d617c4
    9a2aa9b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions