Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
abd26c7
feat: logging foundation – structured LogEvent, JUL handler, Log API …
gnodet Sep 20, 2026
92a187f
feat: build report – structured JSON report with per-mojo log capture
gnodet Sep 21, 2026
27e1395
[MNG-12537] reactor.xml: named build aliases and lifecycle execution …
gnodet Sep 23, 2026
43d7fe3
Add parent attribute to PhaseInjection for precise lifecycle tree pla…
gnodet Sep 23, 2026
dc26c1e
fix: NeedBraces checkstyle violations in ReactorXmlLifecycleProcessor…
gnodet Sep 23, 2026
1802942
fix: address review comments — doc accuracy and exception cause
gnodet Sep 23, 2026
1e9fc25
fix: remove internal class from SPI Javadoc example, fix javadoc unkn…
gnodet Sep 23, 2026
f8b9ff9
fix: wrong module reference in LifecycleProcessor Javadoc, escape <ar…
gnodet Sep 24, 2026
dde08d5
Merge remote-tracking branch 'origin/master' into feature/reactor-xml
gnodet Sep 24, 2026
63ce016
fix: validate phase() predicate name; document dotless-groupId limita…
gnodet Sep 24, 2026
54de779
fix: document dotted-prefix misrouting limitation and fix inaccurate …
gnodet Sep 24, 2026
6413889
fix: merge master, fix IT reactor.xml format and add JUnit 5 deps to ITs
gnodet Oct 7, 2026
3030e07
Merge remote-tracking branch 'gnodet/feature/reactor-xml' into HEAD
gnodet Oct 7, 2026
3bd8268
fix: export org.apache.maven.api.reactor in module-info.java
gnodet Oct 7, 2026
7d50e9e
fix: add 'requires java.logging' to maven-logging module-info
gnodet Oct 7, 2026
2a2afb5
fix: export org.apache.maven.api.build.report in module-info.java
gnodet Oct 7, 2026
aa5f8bf
refactor: extract lifecycle execution filter into standalone PR #13392
gnodet Oct 9, 2026
0d33914
fix: add Modello pluralExceptions to fix alias parsing in reactor.xml
gnodet Oct 9, 2026
23bbd37
fix: add source file to mng-12537 IT so target/classes is created aft…
gnodet Oct 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions apache-maven/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,6 @@ under the License.
<version>${slf4jVersion}</version>
<scope>runtime</scope>
</dependency>
<!-- bridge from java.util.logging (JUL) to SLF4J -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4jVersion}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-connector-basic</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.apache.maven.api.annotations.Immutable;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.cli.cisupport.CIInfo;
import org.apache.maven.api.reactor.ReactorConfig;
import org.apache.maven.api.services.Lookup;
import org.apache.maven.api.services.MessageBuilderFactory;

Expand Down Expand Up @@ -192,6 +193,20 @@ default Optional<OutputStream> stdErr() {
@Nonnull
Optional<CIInfo> ciInfo();

/**
* Returns the parsed {@code .mvn/reactor.xml} configuration, if present.
*
* <p>The configuration is parsed once during invocation setup (pre-DI) and reused downstream.
* When {@code reactor.xml} is absent, this is empty and the legacy {@code maven.config} /
* {@code extensions.xml} files remain in use.
*
* @return an {@link Optional} containing the {@link ReactorConfig}, or empty if {@code reactor.xml}
* was not found
* @since 4.1.0
*/
@Nonnull
Optional<ReactorConfig> reactorConfig();

/**
* Returns the options associated with this invocation request.
*
Expand Down
36 changes: 36 additions & 0 deletions api/maven-api-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,40 @@
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.codehaus.modello</groupId>
<artifactId>modello-maven-plugin</artifactId>
<executions>
<execution>
<id>modello-reactor</id>
<goals>
<goal>velocity</goal>
<goal>xdoc</goal>
<goal>xsd</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<version>1.0.0</version>
<models>
<model>src/main/mdo/reactor.mdo</model>
</models>
<templates>
<template>model.vm</template>
</templates>
<params>
<param>locationTracking=false</param>
<param>generateLocationClasses=false</param>
<param>packageModelV4=org.apache.maven.api.reactor</param>
<param>packageToolV4=org.apache.maven.internal.reactor.io</param>
</params>
<velocityBasedir>${project.basedir}/../../src/mdo</velocityBasedir>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
2 changes: 2 additions & 0 deletions api/maven-api-core/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
exports org.apache.maven.api.feature;
exports org.apache.maven.api.plugin;
exports org.apache.maven.api.plugin.annotations;
exports org.apache.maven.api.build.report;
exports org.apache.maven.api.reactor;
exports org.apache.maven.api.services;
exports org.apache.maven.api.services.xml;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.api;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Immutable;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.reactor.ReactorConfig;

/**
* Describes the invocation context of a Maven build: the flags, properties, and
* environment settings that were active when the build started.
*
* <p>An instance is available via {@link Session#buildEnvironment()} during the build,
* and is also recorded in the structured build report for post-mortem analysis and
* reproducibility.
*
* <h2>What is captured</h2>
* <ul>
* <li>Goals and lifecycle phases requested ({@link #goals()})</li>
* <li>User properties passed via {@code -Dkey=value} ({@link #userProperties()}),
* with sensitive keys redacted — see {@link #userProperties()} for the denylist</li>
* <li>A curated subset of system properties relevant to reproducibility
* ({@link #systemInfo()}): OS name/arch/version, Java vendor and VM name/version,
* Maven home, and available processors</li>
* <li>Local repository path ({@link #localRepository()})</li>
* <li>Explicitly activated or deactivated profiles ({@link #activeProfiles()})</li>
* <li>Selected projects ({@link #selectedProjects()}) and resume-from
* ({@link #resumeFrom()})</li>
* <li>Reactor failure behavior ({@link #reactorFailureBehavior()})</li>
* <li>Offline mode ({@link #offline()}) and snapshot update policy
* ({@link #updateSnapshots()})</li>
* <li>Degree of concurrency ({@link #threads()})</li>
* <li>Transfer-progress suppression ({@link #noTransferProgress()}) and batch mode ({@link #batchMode()})</li>
* </ul>
*
* <h2>What is not yet captured</h2>
* <p>The following information is not currently available through the Maven 4 API
* and therefore cannot be recorded here. It may be added in future versions as
* the API evolves:
* <ul>
* <li><b>Raw command-line arguments</b> ({@code args[]}): the CLI bootstrap layer
* does not surface these through {@code MavenExecutionRequest} or the session</li>
* <li><b>Implicitly activated profiles</b>: profiles activated by OS, JDK, or
* property conditions rather than by explicit {@code -P} flag; computing
* these requires per-project activation and is not available at session level</li>
* </ul>
*
* @since 4.1.0
* @see Session#buildEnvironment()
*/
@Experimental
@Immutable
public interface BuildEnvironment {

/**
* The goals or lifecycle phases that were requested on the command line.
*
* @return the requested goals/phases, never {@code null}
*/
@Nonnull
List<String> goals();

/**
* User properties passed via {@code -Dkey=value} on the command line or via
* {@code --define}.
*
* <p>Sensitive keys are redacted and replaced with {@code "***"}. A key is
* considered sensitive if its lower-case form contains any of:
* {@code password}, {@code passwd}, {@code secret}, {@code token},
* {@code apikey}, {@code api_key}, {@code credential}, {@code passphrase}.
*
* @return the user properties, never {@code null}; values of sensitive keys
* are replaced with {@code "***"}
*/
@Nonnull
Map<String, String> userProperties();

/**
* A curated subset of system properties capturing platform and JVM identity,
* relevant for build reproducibility analysis.
*
* <p>The following keys are included when present:
* {@code os.name}, {@code os.arch}, {@code os.version},
* {@code java.vendor}, {@code java.vm.name}, {@code java.vm.version},
* {@code maven.home}, {@code user.home}, {@code user.name},
* and {@code available.processors} (from {@code Runtime.getRuntime()}).
*
* <p>The full {@code System.getProperties()} map is intentionally not captured:
* it is large, mostly irrelevant, and may contain sensitive values.
*
* @return the curated system info map, never {@code null}
*/
@Nonnull
Map<String, String> systemInfo();

/**
* The path to the local repository used for this build.
*
* @return the local repository path string, never {@code null}
*/
@Nonnull
String localRepository();

/**
* Profiles explicitly activated ({@code -P profileId}) or deactivated
* ({@code -P !profileId}) on the command line.
*
* <p>This list reflects only explicit {@code -P} selections. Profiles activated
* implicitly by OS, JDK, or property conditions are not included here — see
* the class-level javadoc for details.
*
* @return the explicitly selected profiles, never {@code null}; may be empty
*/
@Nonnull
List<String> activeProfiles();

/**
* Projects explicitly selected via {@code -pl} / {@code --projects}.
*
* @return the selected project selectors (e.g. {@code ":my-module"}),
* never {@code null}; empty for a full reactor build
*/
@Nonnull
List<String> selectedProjects();

/**
* The project to resume from, as specified via {@code -rf} / {@code --resume-from}.
*
* @return the resume-from selector, or {@code null} if not specified
*/
String resumeFrom();

/**
* The reactor failure behavior, corresponding to the {@code -ff} / {@code -fae} /
* {@code -fn} flags.
*
* <p>Possible values (matching {@code MavenExecutionRequest} constants):
* <ul>
* <li>{@code "FAIL_FAST"} — stop at first failure ({@code -ff}, default)</li>
* <li>{@code "FAIL_AT_END"} — build all, report failures at end ({@code -fae})</li>
* <li>{@code "FAIL_NEVER"} — always exit with success ({@code -fn})</li>
* </ul>
*
* @return the failure behavior string, never {@code null}
*/
@Nonnull
String reactorFailureBehavior();

/**
* Whether the build was invoked in offline mode ({@code -o} / {@code --offline}).
*
* @return {@code true} if offline mode was active
*/
boolean offline();

/**
* Whether snapshot updates were forced ({@code -U} / {@code --update-snapshots}).
*
* @return {@code true} if snapshot updates were forced
*/
boolean updateSnapshots();

/**
* Whether transfer progress output was suppressed ({@code --no-transfer-progress} / {@code -ntp}).
*
* @return {@code true} if transfer progress was disabled
*/
boolean noTransferProgress();

/**
* Whether the build was invoked in non-interactive (batch) mode ({@code --batch-mode} / {@code -B}).
* Equivalent to {@code !isInteractiveMode()} on {@code MavenExecutionRequest}.
*
* @return {@code true} if batch mode was active
*/
boolean batchMode();

/**
* The degree of concurrency ({@code -T} flag), or {@code 1} for sequential builds.
*
* @return the thread count
*/
int threads();

/**
* The parsed {@code .mvn/reactor.xml} configuration for this build, if present.
*
* <p>This provides access to the reactor-scoped options, extensions, aliases and
* phase injections declared in the project's {@code .mvn/reactor.xml} file.
* Returns {@link Optional#empty()} when no {@code reactor.xml} was found or parsed.
*
* @return the reactor configuration, never {@code null}
*/
@Nonnull
default Optional<ReactorConfig> reactorConfig() {
return Optional.empty();
}
}
13 changes: 13 additions & 0 deletions api/maven-api-core/src/main/java/org/apache/maven/api/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@
@ThreadSafe
public interface Session extends ProtoSession {

/**
* Returns the environment context of this build: the flags, properties, and
* platform settings that were active when the session started.
*
* <p>The returned instance is immutable and captures a snapshot of the invocation
* context (offline mode, user properties, selected projects, etc.).
*
* @return the build environment, never {@code null}
* @since 4.1.0
*/
@Nonnull
BuildEnvironment buildEnvironment();

/**
* Returns the current maven version.
*
Expand Down
Loading
Loading