You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sl...@apache.org on 2026/09/15 23:38:21 UTC

(maven-invoker-plugin) 01/01: Isolate forked IT builds from the invoking shell environment

This is an automated email from the ASF dual-hosted git repository.

slachiewicz pushed a commit to branch agent/isolate-forked-environment
in repository https://gitbox.apache.org/repos/asf/maven-invoker-plugin.git

commit 07bd5aa58dae4e4cd65ab488c9d040602e50b697
Author: Sylwester Lachiewicz <sl...@apache.org>
AuthorDate: Wed Sep 16 01:38:05 2026 +0200

    Isolate forked IT builds from the invoking shell environment
    
    IT builds must not depend on the shell that runs this plugin: without
    this, MAVEN_ARGS from the outer invocation is appended to every IT's
    command line, and ~/.mavenrc/etc silently override invoker.mavenOpts.
    Clear MAVEN_ARGS and set MAVEN_SKIP_RC=1 by default; an IT can still
    override either through environmentVariables or
    invoker.environmentVariables.*.
    
    Fixes #603
    Fixes #635
---
 .../invoker.properties                             |  5 ++
 .../src/it/minvoker-172/pom.xml                    | 56 +++++++++++++++++++
 .../src/it/minvoker-372/pom.xml                    | 63 ++++++++++++++++++++++
 .../invocation-environmentvariable/verify.groovy   | 10 ++++
 .../maven/plugins/invoker/AbstractInvokerMojo.java | 21 ++++++++
 src/site/markdown/examples/invoker-properties.md   |  6 +++
 6 files changed, 161 insertions(+)

diff --git a/src/it/invocation-environmentvariable/invoker.properties b/src/it/invocation-environmentvariable/invoker.properties
index a08c036..b65a1f8 100644
--- a/src/it/invocation-environmentvariable/invoker.properties
+++ b/src/it/invocation-environmentvariable/invoker.properties
@@ -17,3 +17,8 @@
 
 invoker.environmentVariables.MINVOKER273_PROPERTIES1 = minvoker273_properties1
 invoker.environmentVariables.MINVOKER273_PROPERTIES2 = minvoker273_properties2
+
+# MINVOKER-372: simulates a flag left over in the environment of the shell that runs this outer build,
+# e.g. from an unrelated "mvn -Dleaked.arg=true ..." invocation. This only affects this outer build; the
+# plugin under test must not let it leak into the invocations it forks from src/it/minvoker-372 and friends.
+invoker.environmentVariables.MAVEN_ARGS = -Dleaked.arg=true
diff --git a/src/it/invocation-environmentvariable/src/it/minvoker-172/pom.xml b/src/it/invocation-environmentvariable/src/it/minvoker-172/pom.xml
new file mode 100644
index 0000000..76bedcd
--- /dev/null
+++ b/src/it/invocation-environmentvariable/src/it/minvoker-172/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- 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. -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.maven.plugins.invoker.its</groupId>
+  <artifactId>minvoker-172</artifactId>
+  <version>0.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <description>
+    MINVOKER-172: every forked invocation must get MAVEN_SKIP_RC=1 so that ~/.mavenrc and /etc/mavenrc cannot
+    override the MAVEN_OPTS the plugin sets from invoker.mavenOpts.
+  </description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-enforcer-plugin</artifactId>
+        <version>@version.maven-enforcer-plugin@</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>enforce</goal>
+            </goals>
+            <configuration>
+              <rules>
+                <evaluateBeanshell>
+                  <condition><![CDATA[
+                    "${env.MAVEN_SKIP_RC}" == "1"
+                  ]]></condition>
+                </evaluateBeanshell>
+              </rules>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/src/it/invocation-environmentvariable/src/it/minvoker-372/pom.xml b/src/it/invocation-environmentvariable/src/it/minvoker-372/pom.xml
new file mode 100644
index 0000000..aa210ee
--- /dev/null
+++ b/src/it/invocation-environmentvariable/src/it/minvoker-372/pom.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- 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. -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.maven.plugins.invoker.its</groupId>
+  <artifactId>minvoker-372</artifactId>
+  <version>0.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <description>
+    MINVOKER-372: the outer invocation-environmentvariable build sets MAVEN_ARGS=-Dleaked.arg=true in its own
+    environment (see ../../invoker.properties). This project must not see that flag: the "leaked" profile below
+    is only activated, and fails the build, if the leaked.arg property made it into this forked invocation.
+  </description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <profiles>
+    <profile>
+      <id>leaked</id>
+      <activation>
+        <property>
+          <name>leaked.arg</name>
+        </property>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-enforcer-plugin</artifactId>
+            <version>@version.maven-enforcer-plugin@</version>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>enforce</goal>
+                </goals>
+                <configuration>
+                  <rules>
+                    <AlwaysFail />
+                  </rules>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>
diff --git a/src/it/invocation-environmentvariable/verify.groovy b/src/it/invocation-environmentvariable/verify.groovy
index 2a6e7a3..f89cb94 100644
--- a/src/it/invocation-environmentvariable/verify.groovy
+++ b/src/it/invocation-environmentvariable/verify.groovy
@@ -31,3 +31,13 @@ assert buildLod273.contains('MINVOKER273_PROPERTIES2=minvoker273_properties2')
 // MINVOKER273_PROPERTIES3 is not present in system environment and should not be present in invocation
 assert !buildLod273.contains('MINVOKER273_PROPERTIES3')
 
+// MINVOKER-372: MAVEN_ARGS=-Dleaked.arg=true is set on this outer build's own environment (see
+// invoker.properties) but must not leak into the forked invocation of minvoker-372; if it did, the
+// "leaked" profile would activate and fail that build.
+def buildLog372 = new File( basedir, 'src/it/minvoker-372/build.log' ).text
+assert buildLog372.contains('] BUILD SUCCESS')
+
+// MINVOKER-172: every forked invocation gets MAVEN_SKIP_RC=1 so ~/.mavenrc/etc cannot override MAVEN_OPTS.
+def buildLog172 = new File( basedir, 'src/it/minvoker-172/build.log' ).text
+assert buildLog172.contains('] BUILD SUCCESS')
+
diff --git a/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java b/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
index c687ad9..9a4a44b 100644
--- a/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
+++ b/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
@@ -417,6 +417,12 @@ public abstract class AbstractInvokerMojo extends AbstractMojo {
      * Since the version <b>3.7.0</b> using an alternate syntax for mavenOpts, <code>@{...}</code>
      * allows late replacement of properties when the plugin is executed,
      * so properties that have been modified by other plugins will be picked up correctly.
+     * <br>
+     * Since version <b>3.10.2</b>, forked builds also get <code>MAVEN_SKIP_RC</code> set to <code>1</code> so that
+     * <code>~/.mavenrc</code> and <code>/etc/mavenrc</code> cannot silently override this value, and
+     * <code>MAVEN_ARGS</code> is cleared for the same reason (see {@link #environmentVariables}). An IT can still
+     * override <code>MAVEN_SKIP_RC</code> through {@link #environmentVariables} or
+     * <code>invoker.environmentVariables.MAVEN_SKIP_RC</code>.
      *
      * @since 1.2
      */
@@ -527,6 +533,13 @@ public abstract class AbstractInvokerMojo extends AbstractMojo {
 
     /**
      * Additional environment variables to set on the command line.
+     * <br>
+     * Since version <b>3.10.2</b>, each forked IT build is isolated from the environment that invoked this plugin:
+     * <code>MAVEN_ARGS</code> is cleared (so the outer run's <code>-pl</code>, <code>-P</code> and <code>-D</code>
+     * flags are not appended to every IT) and <code>MAVEN_SKIP_RC</code> is set to <code>1</code> (so
+     * <code>~/.mavenrc</code>/<code>/etc/mavenrc</code> cannot override <code>MAVEN_OPTS</code>). Define
+     * <code>MAVEN_ARGS</code> and/or <code>MAVEN_SKIP_RC</code> here, or per invocation through
+     * <code>invoker.environmentVariables.*</code> in the invoker properties, to opt back out.
      *
      * @since 1.8
      */
@@ -1858,6 +1871,14 @@ public abstract class AbstractInvokerMojo extends AbstractMojo {
                 userProperties.putAll(scriptUserProperties);
                 request.setProperties(userProperties);
 
+                // Isolate the forked build from the environment that is invoking this plugin: clear
+                // MAVEN_ARGS so the outer run's -pl/-P/-D flags are not appended to the IT's command
+                // line, and set MAVEN_SKIP_RC so ~/.mavenrc and /etc/mavenrc cannot override the
+                // MAVEN_OPTS set below from invoker.mavenOpts. An IT can still opt out through the
+                // environmentVariables mojo parameter or invoker.environmentVariables.*, applied next.
+                request.addShellEnvironment("MAVEN_ARGS", "");
+                request.addShellEnvironment("MAVEN_SKIP_RC", "1");
+
                 invokerProperties.configureInvocation(request, invocationIndex);
 
                 if (getLog().isDebugEnabled()) {
diff --git a/src/site/markdown/examples/invoker-properties.md b/src/site/markdown/examples/invoker-properties.md
index 51d974e..97d0160 100644
--- a/src/site/markdown/examples/invoker-properties.md
+++ b/src/site/markdown/examples/invoker-properties.md
@@ -167,6 +167,12 @@ invoker.environmentVariables.MY_ENV_NAME = myEnvValue
 invoker.updateSnapshots = true
 ```
 
+Since plugin version 3.10.2, every IT build is isolated from the environment that invoked the plugin: `MAVEN_ARGS`
+is cleared and `MAVEN_SKIP_RC` is set to `1`, so a test build never inherits `-pl`/`-P`/`-D` flags left over in
+`MAVEN_ARGS` by the outer run, and `~/.mavenrc`/`/etc/mavenrc` cannot silently override `MAVEN_OPTS`. Set either
+variable through the `environmentVariables` plugin parameter, or per invocation with
+`invoker.environmentVariables.MAVEN_ARGS`/`invoker.environmentVariables.MAVEN_SKIP_RC`, to opt back out.
+
 The comments given in the example should be rather self-explanatory. Looking closely, you can also notice that the syntax `${expression}` can be used to filter the property values. What deserves some more description is the possibility to perform several Maven builds on the same project. By default, the Invoker Plugin will perform the following steps for each project:
 
 - Run the pre build hook script if existent