Skip to content

Deadlock in AbstractRequestCache when resolving parent POMs with empty local repo #12445

Description

@gnodet

Description

Maven 4 hangs indefinitely during builds when the local repository is empty (e.g. -Dmaven.repo.local=/fresh/path). The build freezes at maven-remote-resources-plugin:process while resolving parent POMs of transitive dependencies.

The same build completes in seconds with a populated local repository.

Steps to Reproduce

git clone --depth 1 https://github.com/apache/httpcomponents-stylecheck.git
cd httpcomponents-stylecheck
# Works fine (cached):
mvn -B clean package -DskipTests
# Hangs forever (empty repo):
mvn -B clean package -DskipTests -Dmaven.repo.local=/tmp/fresh-repo

The build hangs at:

[INFO] --- remote-resources:3.0.0:process (process-resource-bundles) @ hc-stylecheck ---
[INFO] Preparing remote bundle org.apache:apache-jar-resource-bundle:1.4
[INFO] Copying 3 resources from 1 bundle.

Thread Dump Analysis

The main thread is stuck in AbstractRequestCache.lambda$requests$0 (line 95) calling Object.wait() on a HashMap that it already holds the lock on:

"main" in Object.wait()
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait0(Native Method)
    - waiting on <0x000000070dadf9a8> (a java.util.HashMap)
    at org.apache.maven.impl.cache.AbstractRequestCache.lambda$requests$0(AbstractRequestCache.java:95)
    - locked <0x000000070dadf9a8> (a java.util.HashMap)
    at org.apache.maven.impl.cache.CachingSupplier.apply(CachingSupplier.java:50)
    at org.apache.maven.impl.cache.AbstractRequestCache.requests(AbstractRequestCache.java:144)
    at org.apache.maven.impl.AbstractSession.requests(AbstractSession.java:177)
    at org.apache.maven.impl.DefaultArtifactResolver.doResolve(DefaultArtifactResolver.java:106)
    at org.apache.maven.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:65)
    at org.apache.maven.impl.AbstractSession.resolveArtifact(AbstractSession.java:689)
    at org.apache.maven.impl.resolver.DefaultModelResolver.getPath(DefaultModelResolver.java:181)
    at org.apache.maven.impl.resolver.DefaultModelResolver.doResolveModel(DefaultModelResolver.java:155)
    at org.apache.maven.impl.resolver.DefaultModelResolver.resolveModel(DefaultModelResolver.java:116)
    at org.apache.maven.impl.model.DefaultModelBuilder...resolveParent(DefaultModelBuilder.java:1101)
    ...
    at org.apache.maven.plugin.resources.remote.ProcessRemoteResourcesMojo.getProjects(ProcessRemoteResourcesMojo.java:665)

Meanwhile, all 15 worker threads (5× BfDependencyCollector, 5× BasicRepositoryConnector, 5× resolver) are idle in LinkedBlockingQueue.take(), waiting for work that is never submitted.

Root Cause

This appears to be a missed-signal deadlock in AbstractRequestCache / CachingSupplier:

  1. The main thread enters CachingSupplier.apply() to resolve an artifact
  2. Inside, it calls Object.wait() on a HashMap, expecting another thread to resolve the artifact and call notify()
  3. But the resolution work is never dispatched to the worker threads — they sit idle in their thread pool queues
  4. The main thread waits forever

When the local repo is populated, the CachingSupplier returns the cached result immediately without entering the wait path. The deadlock only triggers when actual remote resolution is needed.

Impact

This affects any project using maven-remote-resources-plugin (very common — it's bound by default in the Apache parent POM) when built with a fresh local repository. This is the standard CI scenario where each build starts with an empty local repo.

In the maven4-testing suite (testing ~966 Apache projects against Maven 4), this deadlock caused 21 of 57 failures — all were 1-hour timeouts on projects that build fine on Maven 3 in under 6 minutes.

Environment

  • Maven: 4.1.0-SNAPSHOT (commit 595458c)
  • Java: OpenJDK 25.0.3+9-LTS
  • OS: Linux
  • Plugin: maven-remote-resources-plugin 3.0.0

Full thread dump attached: all 27 threads, showing the main thread's full stack trace and all idle worker threads.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions