apache/maven · warning
{} aggregator mojo is already being executed in this paralle
Error message
{} aggregator mojo is already being executed in this parallel build, those kind of mojos require exclusive access to reactor to prevent race conditions. This mojo execution will be blocked until the aggregator mojo is done. What it means
MojoExecutor guards parallel builds with a read/write lock pair: aggregator mojos take the write lock (exclusive reactor access), all other mojos take a read lock. When a mojo's tryLock() fails because an aggregator mojo currently holds the write lock, Maven logs this warning and blocks the calling thread on aggregatorLock.lock() until the aggregator finishes. It is advisory only — correctness is preserved by the blocking; the message explains the temporary stall in 'mvn -T' builds.
Source
Thrown at impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java:249
*/
protected class ProjectLock implements NoExceptionCloseable {
final Lock acquiredAggregatorLock;
final OwnerReentrantLock acquiredProjectLock;
ProjectLock(MavenSession session, MojoDescriptor mojoDescriptor) {
mojos.put(Thread.currentThread(), mojoDescriptor);
boolean aggregator = mojoDescriptor.isAggregator();
acquiredAggregatorLock = aggregator ? aggregatorLock.writeLock() : aggregatorLock.readLock();
acquiredProjectLock = getProjectLock(session);
if (!acquiredAggregatorLock.tryLock()) {
Thread owner = aggregatorLock.getOwner();
MojoDescriptor ownerMojo = owner != null ? mojos.get(owner) : null;
String str = ownerMojo != null ? " The " + ownerMojo.getId() : "An";
String msg = str + " aggregator mojo is already being executed "
+ "in this parallel build, those kind of mojos require exclusive access to "
+ "reactor to prevent race conditions. This mojo execution will be blocked "
+ "until the aggregator mojo is done.";
warn(msg);
acquiredAggregatorLock.lock();
}
if (!acquiredProjectLock.tryLock()) {
Thread owner = acquiredProjectLock.getOwner();
MojoDescriptor ownerMojo = owner != null ? mojos.get(owner) : null;
String str = ownerMojo != null ? " The " + ownerMojo.getId() : "A";
String msg = str + " mojo is already being executed "
+ "on the project " + session.getCurrentProject().getGroupId()
+ ":" + session.getCurrentProject().getArtifactId() + ". "
+ "This mojo execution will be blocked "
+ "until the mojo is done.";
warn(msg);
acquiredProjectLock.lock();
}
}
@Override
public void close() {View on GitHub (pinned to e4093d4e12)
Solutions
- Treat it as informational: the build is correct, that mojo just waits; if build time is acceptable, no action is needed.
- Run aggregator goals in a separate sequential invocation (e.g. 'mvn -T 1C package' then 'mvn javadoc:aggregate-jar') to remove the stall.
- Reduce thread count (-T 2) or run the whole build without -T if contention dominates wall-clock time.
- Replace the aggregator goal with a per-module goal plus an aggregation step in a later phase, so it need not lock the whole reactor.
Example fix
# before: aggregator goal contends with parallel module builds mvn -T 1C clean install javadoc:aggregate-jar # after: split into a parallel build and a sequential aggregation step mvn -T 1C clean install mvn javadoc:aggregate-jar
Defensive patterns
Strategy: validation
Validate before calling
# guard: detect aggregator goals before enabling -T mvn help:describe -Dplugin=org.apache.maven.plugins:maven-javadoc-plugin -Ddetail \ | grep -i aggregat # if aggregator goals are in the plan, split the run instead of mixing with -T
Prevention
- Run aggregator goals (javadoc:aggregate, license:check on root) as separate sequential invocations after the parallel build.
- Remember the warning is benign: the lock guarantees mutual exclusion; treat it as a wall-clock signal, not an error.
- Budget -T thread counts so one aggregator does not serialize the tail of the build.
When it happens
Trigger: Running with -T/--threads while an aggregator mojo (@Aggregator or requiresProject=false, e.g. 'mvn -T 1C clean install javadoc:aggregate-jar', spotbugs:spotbugs, license:check on the root) is executing; enough other module mojos run concurrently that one of them reaches execute() while the aggregator holds the write lock.
Common situations: CI builds adding -T 1C or -T 4 for speed; aggregator/reporting goals (javadoc:aggregate, license:check, tidy) mixed into the same parallel reactor run; flaky ordering — the warning appears only when lock contention actually happens, so builds intermittently print it.
Related errors
- {} mojo is already being executed on the project {}:{} This
- Failed to interpolate field: " + field + " on class: " + cls
- Invalid threads core multiplier value: '{}'. Value must be p
- Invalid threads value: '{}'. Value must be positive.
- Invalid threads value: '{}'. Supported are int and float val
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/e72b8336365d9bfc.
Report an issue: GitHub.