You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by cs...@apache.org on 2026/05/29 19:50:14 UTC

(maven) branch master updated: Feat: Pull out maven-executor into its own project (#12004)

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

cstamas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git


The following commit(s) were added to refs/heads/master by this push:
     new 15d19f2f62 Feat: Pull out maven-executor into its own project (#12004)
15d19f2f62 is described below

commit 15d19f2f623fc6e2e5489552913215f24e920c60
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Fri May 29 21:50:07 2026 +0200

    Feat: Pull out maven-executor into its own project (#12004)
    
    The main goal of `maven-executor` is ability to execute Maven 3/4 in "embedded" and "forked" mode, and has not related with Maven release lifecycle itself (and is dependency-less as well). So, let's move it out into own project.
    
    https://github.com/apache/maven-executor
    
    The new library executes Maven in:
    * forked or embedded mode, but introduces other providers as well
    * supports Maven 3 and 4
    * the main `maven-executor` module is Java 8, dependency-less library (is MR-JAR, and on 9+ is modular and provides ToolProvider SPI integration as well)
---
 .mvn/maven.config                                  |   5 +-
 impl/maven-executor/pom.xml                        | 149 ------
 .../org/apache/maven/cling/executor/Executor.java  |  75 ---
 .../maven/cling/executor/ExecutorException.java    |  51 --
 .../maven/cling/executor/ExecutorHelper.java       |  80 ----
 .../maven/cling/executor/ExecutorRequest.java      | 518 ---------------------
 .../apache/maven/cling/executor/ExecutorTool.java  |  74 ---
 .../executor/embedded/EmbeddedMavenExecutor.java   | 457 ------------------
 .../cling/executor/forked/ForkedMavenExecutor.java | 226 ---------
 .../maven/cling/executor/internal/HelperImpl.java  | 102 ----
 .../maven/cling/executor/internal/ToolboxTool.java | 170 -------
 impl/maven-executor/src/site/site.xml              |  35 --
 .../apache/maven/cling/executor/Environment.java   |  25 -
 .../cling/executor/MavenExecutorTestSupport.java   | 412 ----------------
 .../embedded/EmbeddedMavenExecutorTest.java        |  33 --
 .../executor/forked/ForkedMavenExecutorTest.java   |  33 --
 .../maven/cling/executor/impl/ToolboxToolTest.java | 211 ---------
 impl/pom.xml                                       |   1 -
 its/core-it-support/maven-it-helper/pom.xml        |   2 +-
 .../main/java/org/apache/maven/it/Verifier.java    |  71 +--
 its/pom.xml                                        |   5 +-
 21 files changed, 45 insertions(+), 2690 deletions(-)

diff --git a/.mvn/maven.config b/.mvn/maven.config
index caa8f5f80c..951ab8ff12 100644
--- a/.mvn/maven.config
+++ b/.mvn/maven.config
@@ -1 +1,4 @@
--DsessionRootDirectory=${session.rootDirectory}
+-D
+sessionRootDirectory=${session.rootDirectory}
+-D
+apache.snapshots
diff --git a/impl/maven-executor/pom.xml b/impl/maven-executor/pom.xml
deleted file mode 100644
index c4712962ce..0000000000
--- a/impl/maven-executor/pom.xml
+++ /dev/null
@@ -1,149 +0,0 @@
-<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache.maven</groupId>
-    <artifactId>maven-impl-modules</artifactId>
-    <version>4.1.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>maven-executor</artifactId>
-
-  <name>Maven 4 Executor</name>
-  <description>Maven 4 Executor, for executing Maven 3/4.</description>
-
-  <properties>
-    <maven3version>3.9.14</maven3version>
-    <maven4version>${project.version}</maven4version>
-    <testTmpDir>${project.build.directory}/tmp</testTmpDir>
-  </properties>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-api-annotations</artifactId>
-      <scope>provided</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>org.junit.jupiter</groupId>
-      <artifactId>junit-jupiter-api</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.junit.jupiter</groupId>
-      <artifactId>junit-jupiter-params</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>eu.maveniverse.maven.mimir</groupId>
-      <artifactId>testing</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>apache-maven</artifactId>
-      <version>${project.version}</version>
-      <classifier>bin</classifier>
-      <type>zip</type>
-      <scope>test</scope>
-      <exclusions>
-        <exclusion>
-          <groupId>*</groupId>
-          <artifactId>*</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>prepare-maven4-distro</id>
-            <goals>
-              <goal>unpack-dependencies</goal>
-            </goals>
-            <phase>generate-test-resources</phase>
-            <configuration>
-              <includeArtifactIds>apache-maven</includeArtifactIds>
-            </configuration>
-          </execution>
-          <execution>
-            <id>prepare-maven3-distro</id>
-            <goals>
-              <goal>unpack</goal>
-            </goals>
-            <phase>generate-test-resources</phase>
-            <configuration>
-              <artifactItems>
-                <artifactItem>
-                  <groupId>org.apache.maven</groupId>
-                  <artifactId>apache-maven</artifactId>
-                  <version>${maven3version}</version>
-                  <classifier>bin</classifier>
-                  <type>zip</type>
-                </artifactItem>
-              </artifactItems>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-antrun-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>create-tmp-dir</id>
-            <goals>
-              <goal>run</goal>
-            </goals>
-            <phase>process-test-resources</phase>
-            <configuration>
-              <target>
-                <mkdir dir="${testTmpDir}" />
-              </target>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <promoteUserPropertiesToSystemProperties>false</promoteUserPropertiesToSystemProperties>
-          <systemPropertyVariables>
-            <maven3version>${maven3version}</maven3version>
-            <maven4version>${maven4version}</maven4version>
-            <maven3home>${project.build.directory}/dependency/apache-maven-${maven3version}</maven3home>
-            <maven4home>${project.build.directory}/dependency/apache-maven-${maven4version}</maven4home>
-            <localRepository>${settings.localRepository}</localRepository>
-          </systemPropertyVariables>
-          <argLine>-Xmx256m @{jacocoArgLine} -Djava.io.tmpdir=${testTmpDir}</argLine>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/Executor.java b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/Executor.java
deleted file mode 100644
index 80107a9b8c..0000000000
--- a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/Executor.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.cling.executor;
-
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Nonnull;
-
-/**
- * Defines the contract for a component responsible for executing a Maven tool
- * using the information provided in an {@link ExecutorRequest}. This interface is central
- * to the execution of Maven commands and builds, but it does not construct nor fully parses arguments.
- *
- * @since 4.0.0
- */
-@Experimental
-public interface Executor extends AutoCloseable {
-    // Logic borrowed from Commons-Lang3
-    boolean IS_WINDOWS = System.getProperty("os.name", "unknown").startsWith("Windows");
-
-    /**
-     * Maven version string returned when the actual version of Maven cannot be determined.
-     */
-    String UNKNOWN_VERSION = "unknown";
-
-    /**
-     * Invokes the tool application using the provided {@link ExecutorRequest}.
-     * This method is responsible for executing the command or build
-     * process based on the information contained in the request.
-     *
-     * @param executorRequest the request containing all necessary information for the execution
-     * @return an integer representing the exit code of the execution (0 typically indicates success)
-     * @throws ExecutorException if an error occurs during the execution process
-     */
-    int execute(@Nonnull ExecutorRequest executorRequest) throws ExecutorException;
-
-    /**
-     * Returns the Maven version that provided {@link ExecutorRequest} point at (would use). This
-     * operation, depending on the underlying implementation, can be costly. If a caller uses this method often, it is
-     * the caller's responsibility to properly cache returned values. (key can be {@link ExecutorRequest#installationDirectory()}.
-     *
-     * @param executorRequest the request containing all necessary information for the execution
-     * @return a string representing the Maven version or {@link #UNKNOWN_VERSION}
-     * @throws ExecutorException if an error occurs during the execution process
-     */
-    @Nonnull
-    String mavenVersion(@Nonnull ExecutorRequest executorRequest) throws ExecutorException;
-
-    /**
-     * Closes and disposes of this {@link Executor} instance, releasing any resources it may hold.
-     * This method is called automatically when using try-with-resources statements.
-     *
-     * <p>The default implementation does nothing. Subclasses should override this method
-     * if they need to perform cleanup operations.</p>
-     *
-     * @throws ExecutorException if an error occurs while closing the {@link Executor}
-     */
-    @Override
-    void close() throws ExecutorException;
-}
diff --git a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorException.java b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorException.java
deleted file mode 100644
index 8d8fbfde43..0000000000
--- a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorException.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.cling.executor;
-
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Nullable;
-
-/**
- * Represents an exception that occurs during the execution of a Maven build or command.
- * This exception is typically thrown when there are errors during the execution of a Maven
- * process, such as wrong cwd, non-existent installation directory, or other runtime issues.
- *
- * @since 4.0.0
- */
-@Experimental
-public class ExecutorException extends RuntimeException {
-    /**
-     * Constructs a new {@code InvokerException} with the specified detail message.
-     *
-     * @param message the detail message explaining the cause of the exception
-     */
-    public ExecutorException(@Nullable String message) {
-        super(message);
-    }
-
-    /**
-     * Constructs a new {@code InvokerException} with the specified detail message and cause.
-     *
-     * @param message the detail message explaining the cause of the exception
-     * @param cause the underlying cause of the exception
-     */
-    public ExecutorException(@Nullable String message, @Nullable Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorHelper.java b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorHelper.java
deleted file mode 100644
index 8aea8b2a52..0000000000
--- a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorHelper.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.cling.executor;
-
-import org.apache.maven.api.annotations.Nonnull;
-
-/**
- * Helper class for routing Maven execution based on preferences and/or issued execution requests.
- */
-public interface ExecutorHelper {
-    /**
-     * The modes of execution.
-     */
-    enum Mode {
-        /**
-         * Automatically decide. For example, presence of {@link ExecutorRequest#environmentVariables()} or
-         * {@link ExecutorRequest#jvmArguments()} will result in choosing {@link #FORKED} executor. Otherwise,
-         * {@link #EMBEDDED} executor is preferred.
-         */
-        AUTO,
-        /**
-         * Forces embedded execution. May fail if {@link ExecutorRequest} contains input unsupported by executor.
-         */
-        EMBEDDED,
-        /**
-         * Forces forked execution. Always carried out, most isolated and "most correct", but is slow as it uses child process.
-         */
-        FORKED
-    }
-
-    /**
-     * Returns the preferred mode of this helper.
-     */
-    @Nonnull
-    Mode getDefaultMode();
-
-    /**
-     * Creates pre-populated builder for {@link ExecutorRequest}. Users of helper must use this method to create
-     * properly initialized request builder.
-     */
-    @Nonnull
-    ExecutorRequest.Builder executorRequest();
-
-    /**
-     * Executes the request with preferred mode executor.
-     */
-    default int execute(ExecutorRequest executorRequest) throws ExecutorException {
-        return execute(getDefaultMode(), executorRequest);
-    }
-
-    /**
-     * Executes the request with passed in mode executor.
-     */
-    int execute(Mode mode, ExecutorRequest executorRequest) throws ExecutorException;
-
-    /**
-     * High level operation, returns the version of the Maven covered by this helper. This method call caches
-     * underlying operation, and is safe to invoke as many times needed.
-     *
-     * @see Executor#mavenVersion(ExecutorRequest)
-     */
-    @Nonnull
-    String mavenVersion();
-}
diff --git a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorRequest.java b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorRequest.java
deleted file mode 100644
index 1e7118f0b6..0000000000
--- a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorRequest.java
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
- * 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.cling.executor;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.HashMap;
-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.annotations.Nullable;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- * Represents a request to execute Maven with command-line arguments.
- * This interface encapsulates all the necessary information needed to execute
- * Maven command with arguments. The arguments are not parsed, they are just passed over
- * to executed tool.
- *
- * @since 4.0.0
- */
-@Immutable
-@Experimental
-public interface ExecutorRequest {
-    /**
-     * The Maven command.
-     */
-    String MVN = "mvn";
-
-    /**
-     * The command to execute, ie "mvn".
-     */
-    @Nonnull
-    String command();
-
-    /**
-     * The immutable list of arguments to pass to the command.
-     */
-    @Nonnull
-    List<String> arguments();
-
-    /**
-     * Returns the current working directory for the Maven execution.
-     * This is typically the directory from which Maven was invoked.
-     *
-     * @return the current working directory path
-     */
-    @Nonnull
-    Path cwd();
-
-    /**
-     * Returns the Maven installation directory.
-     * This is usually set by the Maven launcher script using the "maven.home" system property.
-     *
-     * @return the Maven installation directory path
-     */
-    @Nonnull
-    Path installationDirectory();
-
-    /**
-     * Returns the user's home directory.
-     * This is typically obtained from the "user.home" system property.
-     *
-     * @return the user's home directory path
-     */
-    @Nonnull
-    Path userHomeDirectory();
-
-    /**
-     * Returns the map of Java System Properties to set before executing process.
-     *
-     * @return an Optional containing the map of Java System Properties, or empty if not specified
-     */
-    @Nonnull
-    Optional<Map<String, String>> jvmSystemProperties();
-
-    /**
-     * Returns the map of environment variables to set before executing process.
-     * This property is used ONLY by executors that spawn a new JVM.
-     *
-     * @return an Optional containing the map of environment variables, or empty if not specified
-     */
-    @Nonnull
-    Optional<Map<String, String>> environmentVariables();
-
-    /**
-     * Returns the list of extra JVM arguments to be passed to the forked process.
-     * These arguments allow for customization of the JVM environment in which tool will run.
-     * This property is used ONLY by executors that spawn a new JVM.
-     *
-     * @return an Optional containing the list of extra JVM arguments, or empty if not specified
-     */
-    @Nonnull
-    Optional<List<String>> jvmArguments();
-
-    /**
-     * Optional provider for STD in of the Maven. If given, this provider will be piped into std input of
-     * Maven.
-     *
-     * @return an Optional containing the stdin provider, or empty if not specified.
-     */
-    Optional<InputStream> stdIn();
-
-    /**
-     * Optional consumer for STD out of the Maven. If given, this consumer will get all output from the std out of
-     * Maven. Note: whether consumer gets to consume anything depends on invocation arguments passed in
-     * {@link #arguments()}, as if log file is set, not much will go to stdout.
-     *
-     * @return an Optional containing the stdout consumer, or empty if not specified.
-     */
-    Optional<OutputStream> stdOut();
-
-    /**
-     * Optional consumer for STD err of the Maven. If given, this consumer will get all output from the std err of
-     * Maven. Note: whether consumer gets to consume anything depends on invocation arguments passed in
-     * {@link #arguments()}, as if log file is set, not much will go to stderr.
-     *
-     * @return an Optional containing the stderr consumer, or empty if not specified.
-     */
-    Optional<OutputStream> stdErr();
-
-    /**
-     * Indicate if {@code ~/.mavenrc} should be skipped during execution.
-     * <p>
-     * Affected only for forked executor by adding MAVEN_SKIP_RC environment variable
-     */
-    boolean skipMavenRc();
-
-    /**
-     * Returns {@link Builder} created from this instance.
-     */
-    @Nonnull
-    default Builder toBuilder() {
-        return new Builder(
-                command(),
-                arguments(),
-                cwd(),
-                installationDirectory(),
-                userHomeDirectory(),
-                jvmSystemProperties().orElse(null),
-                environmentVariables().orElse(null),
-                jvmArguments().orElse(null),
-                stdIn().orElse(null),
-                stdOut().orElse(null),
-                stdErr().orElse(null),
-                skipMavenRc());
-    }
-
-    /**
-     * Returns new builder pre-set to run Maven. The discovery of maven home is attempted, user cwd and home are
-     * also discovered by standard means.
-     */
-    @Nonnull
-    static Builder mavenBuilder(@Nullable Path installationDirectory) {
-        return new Builder(
-                MVN,
-                null,
-                getCanonicalPath(Paths.get(System.getProperty("user.dir"))),
-                installationDirectory != null
-                        ? getCanonicalPath(installationDirectory)
-                        : discoverInstallationDirectory(),
-                getCanonicalPath(Paths.get(System.getProperty("user.home"))),
-                null,
-                null,
-                null,
-                null,
-                null,
-                null,
-                false);
-    }
-
-    class Builder {
-        private String command;
-        private List<String> arguments;
-        private Path cwd;
-        private Path installationDirectory;
-        private Path userHomeDirectory;
-        private Map<String, String> jvmSystemProperties;
-        private Map<String, String> environmentVariables;
-        private List<String> jvmArguments;
-        private InputStream stdIn;
-        private OutputStream stdOut;
-        private OutputStream stdErr;
-        private boolean skipMavenRc;
-
-        private Builder() {}
-
-        @SuppressWarnings("ParameterNumber")
-        private Builder(
-                String command,
-                List<String> arguments,
-                Path cwd,
-                Path installationDirectory,
-                Path userHomeDirectory,
-                Map<String, String> jvmSystemProperties,
-                Map<String, String> environmentVariables,
-                List<String> jvmArguments,
-                InputStream stdIn,
-                OutputStream stdOut,
-                OutputStream stdErr,
-                boolean skipMavenRc) {
-            this.command = command;
-            this.arguments = arguments;
-            this.cwd = cwd;
-            this.installationDirectory = installationDirectory;
-            this.userHomeDirectory = userHomeDirectory;
-            this.jvmSystemProperties = jvmSystemProperties;
-            this.environmentVariables = environmentVariables;
-            this.jvmArguments = jvmArguments;
-            this.stdIn = stdIn;
-            this.stdOut = stdOut;
-            this.stdErr = stdErr;
-            this.skipMavenRc = skipMavenRc;
-        }
-
-        @Nonnull
-        public Builder command(String command) {
-            this.command = requireNonNull(command, "command");
-            return this;
-        }
-
-        @Nonnull
-        public Builder arguments(List<String> arguments) {
-            this.arguments = requireNonNull(arguments, "arguments");
-            return this;
-        }
-
-        @Nonnull
-        public Builder argument(String argument) {
-            if (arguments == null) {
-                arguments = new ArrayList<>();
-            }
-            this.arguments.add(requireNonNull(argument, "argument"));
-            return this;
-        }
-
-        @Nonnull
-        public Builder cwd(Path cwd) {
-            this.cwd = getCanonicalPath(requireNonNull(cwd, "cwd"));
-            return this;
-        }
-
-        @Nonnull
-        public Builder installationDirectory(Path installationDirectory) {
-            this.installationDirectory =
-                    getCanonicalPath(requireNonNull(installationDirectory, "installationDirectory"));
-            return this;
-        }
-
-        @Nonnull
-        public Builder userHomeDirectory(Path userHomeDirectory) {
-            this.userHomeDirectory = getCanonicalPath(requireNonNull(userHomeDirectory, "userHomeDirectory"));
-            return this;
-        }
-
-        @Nonnull
-        public Builder jvmSystemProperties(Map<String, String> jvmSystemProperties) {
-            this.jvmSystemProperties = jvmSystemProperties;
-            return this;
-        }
-
-        @Nonnull
-        public Builder jvmSystemProperty(String key, String value) {
-            requireNonNull(key, "env key");
-            requireNonNull(value, "env value");
-            if (jvmSystemProperties == null) {
-                this.jvmSystemProperties = new HashMap<>();
-            }
-            this.jvmSystemProperties.put(key, value);
-            return this;
-        }
-
-        @Nonnull
-        public Builder environmentVariables(Map<String, String> environmentVariables) {
-            this.environmentVariables = environmentVariables;
-            return this;
-        }
-
-        @Nonnull
-        public Builder environmentVariable(String key, String value) {
-            requireNonNull(key, "env key");
-            requireNonNull(value, "env value");
-            if (environmentVariables == null) {
-                this.environmentVariables = new HashMap<>();
-            }
-            this.environmentVariables.put(key, value);
-            return this;
-        }
-
-        @Nonnull
-        public Builder jvmArguments(List<String> jvmArguments) {
-            this.jvmArguments = jvmArguments;
-            return this;
-        }
-
-        @Nonnull
-        public Builder jvmArgument(String jvmArgument) {
-            if (jvmArguments == null) {
-                jvmArguments = new ArrayList<>();
-            }
-            this.jvmArguments.add(requireNonNull(jvmArgument, "jvmArgument"));
-            return this;
-        }
-
-        @Nonnull
-        public Builder stdIn(InputStream stdIn) {
-            this.stdIn = stdIn;
-            return this;
-        }
-
-        @Nonnull
-        public Builder stdOut(OutputStream stdOut) {
-            this.stdOut = stdOut;
-            return this;
-        }
-
-        @Nonnull
-        public Builder stdErr(OutputStream stdErr) {
-            this.stdErr = stdErr;
-            return this;
-        }
-
-        @Nonnull
-        public Builder skipMavenRc(boolean skipMavenRc) {
-            this.skipMavenRc = skipMavenRc;
-            return this;
-        }
-
-        @Nonnull
-        public ExecutorRequest build() {
-            return new Impl(
-                    command,
-                    arguments,
-                    cwd,
-                    installationDirectory,
-                    userHomeDirectory,
-                    jvmSystemProperties,
-                    environmentVariables,
-                    jvmArguments,
-                    stdIn,
-                    stdOut,
-                    stdErr,
-                    skipMavenRc);
-        }
-
-        private static class Impl implements ExecutorRequest {
-            private final String command;
-            private final List<String> arguments;
-            private final Path cwd;
-            private final Path installationDirectory;
-            private final Path userHomeDirectory;
-            private final Map<String, String> jvmSystemProperties;
-            private final Map<String, String> environmentVariables;
-            private final List<String> jvmArguments;
-            private final InputStream stdIn;
-            private final OutputStream stdOut;
-            private final OutputStream stdErr;
-            private final boolean skipMavenRc;
-
-            @SuppressWarnings("ParameterNumber")
-            private Impl(
-                    String command,
-                    List<String> arguments,
-                    Path cwd,
-                    Path installationDirectory,
-                    Path userHomeDirectory,
-                    Map<String, String> jvmSystemProperties,
-                    Map<String, String> environmentVariables,
-                    List<String> jvmArguments,
-                    InputStream stdIn,
-                    OutputStream stdOut,
-                    OutputStream stdErr,
-                    boolean skipMavenRc) {
-                this.command = requireNonNull(command);
-                this.arguments = arguments == null ? List.of() : List.copyOf(arguments);
-                this.cwd = getCanonicalPath(requireNonNull(cwd));
-                this.installationDirectory = getCanonicalPath(requireNonNull(installationDirectory));
-                this.userHomeDirectory = getCanonicalPath(requireNonNull(userHomeDirectory));
-                this.jvmSystemProperties = jvmSystemProperties != null && !jvmSystemProperties.isEmpty()
-                        ? Map.copyOf(jvmSystemProperties)
-                        : null;
-                this.environmentVariables = environmentVariables != null && !environmentVariables.isEmpty()
-                        ? Map.copyOf(environmentVariables)
-                        : null;
-                this.jvmArguments = jvmArguments != null && !jvmArguments.isEmpty() ? List.copyOf(jvmArguments) : null;
-                this.stdIn = stdIn;
-                this.stdOut = stdOut;
-                this.stdErr = stdErr;
-                this.skipMavenRc = skipMavenRc;
-            }
-
-            @Override
-            public String command() {
-                return command;
-            }
-
-            @Override
-            public List<String> arguments() {
-                return arguments;
-            }
-
-            @Override
-            public Path cwd() {
-                return cwd;
-            }
-
-            @Override
-            public Path installationDirectory() {
-                return installationDirectory;
-            }
-
-            @Override
-            public Path userHomeDirectory() {
-                return userHomeDirectory;
-            }
-
-            @Override
-            public Optional<Map<String, String>> jvmSystemProperties() {
-                return Optional.ofNullable(jvmSystemProperties);
-            }
-
-            @Override
-            public Optional<Map<String, String>> environmentVariables() {
-                return Optional.ofNullable(environmentVariables);
-            }
-
-            @Override
-            public Optional<List<String>> jvmArguments() {
-                return Optional.ofNullable(jvmArguments);
-            }
-
-            @Override
-            public Optional<InputStream> stdIn() {
-                return Optional.ofNullable(stdIn);
-            }
-
-            @Override
-            public Optional<OutputStream> stdOut() {
-                return Optional.ofNullable(stdOut);
-            }
-
-            @Override
-            public Optional<OutputStream> stdErr() {
-                return Optional.ofNullable(stdErr);
-            }
-
-            @Override
-            public boolean skipMavenRc() {
-                return skipMavenRc;
-            }
-
-            @Override
-            public String toString() {
-                return getClass().getSimpleName() + "{" + "command='"
-                        + command + '\'' + ", arguments="
-                        + arguments + ", cwd="
-                        + cwd + ", installationDirectory="
-                        + installationDirectory + ", userHomeDirectory="
-                        + userHomeDirectory + ", jvmSystemProperties="
-                        + jvmSystemProperties + ", environmentVariables="
-                        + environmentVariables + ", jvmArguments="
-                        + jvmArguments + ", stdinProvider="
-                        + stdIn + ", stdoutConsumer="
-                        + stdOut + ", stderrConsumer="
-                        + stdErr + ", skipMavenRc="
-                        + skipMavenRc + "}";
-            }
-        }
-    }
-
-    @Nonnull
-    static Path discoverInstallationDirectory() {
-        String mavenHome = System.getProperty("maven.home");
-        if (mavenHome == null) {
-            throw new ExecutorException("requires maven.home Java System Property set");
-        }
-        return getCanonicalPath(Paths.get(mavenHome));
-    }
-
-    @Nonnull
-    static Path discoverUserHomeDirectory() {
-        String userHome = System.getProperty("user.home");
-        if (userHome == null) {
-            throw new ExecutorException("requires user.home Java System Property set");
-        }
-        return getCanonicalPath(Paths.get(userHome));
-    }
-
-    @Nonnull
-    static Path getCanonicalPath(Path path) {
-        requireNonNull(path, "path");
-        return path.toAbsolutePath().normalize();
-    }
-}
diff --git a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorTool.java b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorTool.java
deleted file mode 100644
index 4a9776742f..0000000000
--- a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorTool.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.cling.executor;
-
-import java.util.Map;
-
-import org.apache.maven.api.annotations.Nullable;
-
-/**
- * A tool implementing some common Maven operations.
- */
-public interface ExecutorTool {
-    /**
-     * Performs a diagnostic dump of the environment.
-     *
-     * @param request never {@code null}
-     */
-    Map<String, String> dump(ExecutorRequest.Builder request) throws ExecutorException;
-
-    /**
-     * Returns the location of local repository, as detected by Maven. The {@code userSettings} param may contain
-     * some override (equivalent of {@code -s settings.xml} on CLI).
-     *
-     * @param request never {@code null}
-     */
-    String localRepository(ExecutorRequest.Builder request) throws ExecutorException;
-
-    /**
-     * Returns relative (to {@link #localRepository(ExecutorRequest.Builder)}) path of given artifact in local repository.
-     *
-     * @param request never {@code null}
-     * @param gav the usual resolver artifact GAV string, never {@code null}
-     * @param repositoryId the remote repository ID in case "remote artifact" is asked for
-     */
-    String artifactPath(ExecutorRequest.Builder request, String gav, @Nullable String repositoryId)
-            throws ExecutorException;
-
-    /**
-     * Returns relative (to {@link #localRepository(ExecutorRequest.Builder)}) path of given metadata in local repository.
-     * The metadata coordinates in form of {@code [G]:[A]:[V]:[type]}. Absence of {@code A} implies absence of {@code V}
-     * as well (in other words, it can be {@code G}, {@code G:A} or {@code G:A:V}). The absence of {@code type} implies
-     * it is "maven-metadata.xml". The simplest spec string is {@code :::}.
-     * <p>
-     * Examples:
-     * <ul>
-     *     <li>{@code :::} is root metadata named "maven-metadata.xml"</li>
-     *     <li>{@code :::my-metadata.xml} is root metadata named "my-metadata.xml"</li>
-     *     <li>{@code G:::} equals to {@code G:::maven-metadata.xml}</li>
-     *     <li>{@code G:A::} equals to {@code G:A::maven-metadata.xml}</li>
-     * </ul>
-     *
-     * @param request never {@code null}
-     * @param gav the resolver metadata GAV string
-     * @param repositoryId the remote repository ID in case "remote metadata" is asked for
-     */
-    String metadataPath(ExecutorRequest.Builder request, String gav, @Nullable String repositoryId)
-            throws ExecutorException;
-}
diff --git a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/embedded/EmbeddedMavenExecutor.java b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/embedded/EmbeddedMavenExecutor.java
deleted file mode 100644
index 0e2ddaa4f6..0000000000
--- a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/embedded/EmbeddedMavenExecutor.java
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * 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.cling.executor.embedded;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Function;
-import java.util.stream.Stream;
-
-import org.apache.maven.cling.executor.Executor;
-import org.apache.maven.cling.executor.ExecutorException;
-import org.apache.maven.cling.executor.ExecutorRequest;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- * Embedded executor implementation, that invokes Maven from installation directory within this same JVM but in isolated
- * classloader. This class supports Maven 4.x and Maven 3.x as well. The ClassWorld of Maven is kept in memory as
- * long as instance of this class is not closed. Subsequent execution requests over same installation home are cached.
- */
-public class EmbeddedMavenExecutor implements Executor {
-    /**
-     * Maven4 supports multiple commands from same installation directory.
-     */
-    protected static final Map<String, String> MVN4_MAIN_CLASSES = Map.of(
-            "mvn",
-            "org.apache.maven.cling.MavenCling",
-            "mvnenc",
-            "org.apache.maven.cling.MavenEncCling",
-            "mvnsh",
-            "org.apache.maven.cling.MavenShellCling");
-
-    /**
-     * Context holds things loaded up from given Maven Installation Directory.
-     */
-    protected static final class Context {
-        private final URLClassLoader bootClassLoader;
-        private final String version;
-        private final Object classWorld;
-        private final Set<String> originalClassRealmIds;
-        private final ClassLoader tccl;
-        private final Map<String, Function<ExecutorRequest, Integer>> commands; // the commands
-        private final Collection<Object> keepAlive; // refs things to make sure no GC takes it away
-
-        private Context(
-                URLClassLoader bootClassLoader,
-                String version,
-                Object classWorld,
-                Set<String> originalClassRealmIds,
-                ClassLoader tccl,
-                Map<String, Function<ExecutorRequest, Integer>> commands,
-                Collection<Object> keepAlive) {
-            this.bootClassLoader = bootClassLoader;
-            this.version = version;
-            this.classWorld = classWorld;
-            this.originalClassRealmIds = originalClassRealmIds;
-            this.tccl = tccl;
-            this.commands = commands;
-            this.keepAlive = keepAlive;
-        }
-    }
-
-    protected final boolean cacheContexts;
-    protected final boolean useMavenArgsEnv;
-    protected final AtomicBoolean closed;
-    protected final InputStream originalStdin;
-    protected final PrintStream originalStdout;
-    protected final PrintStream originalStderr;
-    protected final Properties originalProperties;
-    protected final ClassLoader originalClassLoader;
-    protected final ConcurrentHashMap<Path, Context> contexts;
-
-    public EmbeddedMavenExecutor() {
-        this(true, true);
-    }
-
-    public EmbeddedMavenExecutor(boolean cacheContexts, boolean useMavenArgsEnv) {
-        this.cacheContexts = cacheContexts;
-        this.useMavenArgsEnv = useMavenArgsEnv;
-        this.closed = new AtomicBoolean(false);
-        this.originalStdin = System.in;
-        this.originalStdout = System.out;
-        this.originalStderr = System.err;
-        this.originalClassLoader = Thread.currentThread().getContextClassLoader();
-        this.contexts = new ConcurrentHashMap<>();
-        this.originalProperties = new Properties();
-        this.originalProperties.putAll(System.getProperties());
-    }
-
-    @Override
-    public int execute(ExecutorRequest executorRequest) throws ExecutorException {
-        requireNonNull(executorRequest);
-        if (closed.get()) {
-            throw new ExecutorException("Executor is closed");
-        }
-        validate(executorRequest);
-        Context context = mayCreate(executorRequest);
-        String command = executorRequest.command();
-        Function<ExecutorRequest, Integer> exec = context.commands.get(command);
-        if (exec == null) {
-            throw new IllegalArgumentException(
-                    "Unknown command: '" + command + "' for '" + executorRequest.installationDirectory() + "'");
-        }
-
-        Thread.currentThread().setContextClassLoader(context.tccl);
-        try {
-            return exec.apply(executorRequest);
-        } catch (Exception e) {
-            throw new ExecutorException("Failed to execute", e);
-        } finally {
-            try {
-                disposeRuntimeCreatedRealms(context);
-            } finally {
-                System.setIn(originalStdin);
-                System.setOut(originalStdout);
-                System.setErr(originalStderr);
-                Thread.currentThread().setContextClassLoader(originalClassLoader);
-                System.setProperties(originalProperties);
-                if (!cacheContexts) {
-                    doClose(context);
-                }
-            }
-        }
-    }
-
-    /**
-     * Unloads dynamically loaded things, like extensions created realms. Makes sure we go back to "initial state".
-     */
-    protected void disposeRuntimeCreatedRealms(Context context) {
-        try {
-            Method getRealms = context.classWorld.getClass().getMethod("getRealms");
-            Method disposeRealm = context.classWorld.getClass().getMethod("disposeRealm", String.class);
-            List<Object> realms = (List<Object>) getRealms.invoke(context.classWorld);
-            for (Object realm : realms) {
-                String realmId = (String) realm.getClass().getMethod("getId").invoke(realm);
-                if (!context.originalClassRealmIds.contains(realmId)) {
-                    disposeRealm.invoke(context.classWorld, realmId);
-                }
-            }
-        } catch (Exception e) {
-            throw new ExecutorException("Failed to dispose runtime created realms", e);
-        }
-    }
-
-    @Override
-    public String mavenVersion(ExecutorRequest executorRequest) throws ExecutorException {
-        requireNonNull(executorRequest);
-        if (closed.get()) {
-            throw new ExecutorException("Executor is closed");
-        }
-        validate(executorRequest);
-        return mayCreate(executorRequest).version;
-    }
-
-    protected Context mayCreate(ExecutorRequest executorRequest) {
-        Path mavenHome = ExecutorRequest.getCanonicalPath(executorRequest.installationDirectory());
-        if (cacheContexts) {
-            return contexts.computeIfAbsent(mavenHome, k -> doCreate(mavenHome, executorRequest));
-        } else {
-            return doCreate(mavenHome, executorRequest);
-        }
-    }
-
-    protected Context doCreate(Path mavenHome, ExecutorRequest executorRequest) {
-        if (!Files.isDirectory(mavenHome)) {
-            throw new IllegalArgumentException("Installation directory must point to existing directory: " + mavenHome);
-        }
-        if (!MVN4_MAIN_CLASSES.containsKey(executorRequest.command())) {
-            throw new IllegalArgumentException(
-                    getClass().getSimpleName() + " does not support command " + executorRequest.command());
-        }
-        if (executorRequest.environmentVariables().isPresent()) {
-            throw new IllegalArgumentException(getClass().getSimpleName() + " does not support environment variables: "
-                    + executorRequest.environmentVariables().get());
-        }
-        if (executorRequest.jvmArguments().isPresent()) {
-            throw new IllegalArgumentException(getClass().getSimpleName() + " does not support jvmArguments: "
-                    + executorRequest.jvmArguments().get());
-        }
-        Path boot = mavenHome.resolve("boot");
-        Path m2conf = mavenHome.resolve("bin/m2.conf");
-        if (!Files.isDirectory(boot) || !Files.isRegularFile(m2conf)) {
-            throw new IllegalArgumentException(
-                    "Installation directory does not point to Maven installation: " + mavenHome);
-        }
-
-        ArrayList<String> mavenArgs = new ArrayList<>();
-        String mavenArgsEnv = System.getenv("MAVEN_ARGS");
-        if (useMavenArgsEnv && mavenArgsEnv != null && !mavenArgsEnv.isEmpty()) {
-            Arrays.stream(mavenArgsEnv.split(" "))
-                    .filter(s -> !s.trim().isEmpty())
-                    .forEach(s -> mavenArgs.add(0, s));
-        }
-
-        Properties properties = prepareProperties(executorRequest);
-        // set ahead of time, if the mavenHome points to Maven4, as ClassWorld Launcher needs this property
-        properties.setProperty(
-                "maven.mainClass", requireNonNull(MVN4_MAIN_CLASSES.get(ExecutorRequest.MVN), "mainClass"));
-        System.setProperties(properties);
-        URLClassLoader bootClassLoader = createMavenBootClassLoader(boot, Collections.emptyList());
-        Thread.currentThread().setContextClassLoader(bootClassLoader);
-        try {
-            Class<?> launcherClass = bootClassLoader.loadClass("org.codehaus.plexus.classworlds.launcher.Launcher");
-            Object launcher = launcherClass.getDeclaredConstructor().newInstance();
-            Method configure = launcherClass.getMethod("configure", InputStream.class);
-            try (InputStream inputStream = Files.newInputStream(m2conf)) {
-                configure.invoke(launcher, inputStream);
-            }
-            Object classWorld = launcherClass.getMethod("getWorld").invoke(launcher);
-            Set<String> originalClassRealmIds = new HashSet<>();
-
-            // collect pre-created (in m2.conf) class realms as "original ones"; the rest are created at runtime
-            Method getRealms = classWorld.getClass().getMethod("getRealms");
-            List<Object> realms = (List<Object>) getRealms.invoke(classWorld);
-            for (Object realm : realms) {
-                Method realmGetId = realm.getClass().getMethod("getId");
-                originalClassRealmIds.add((String) realmGetId.invoke(realm));
-            }
-
-            Class<?> cliClass =
-                    (Class<?>) launcherClass.getMethod("getMainClass").invoke(launcher);
-            String version = getMavenVersion(cliClass);
-            Map<String, Function<ExecutorRequest, Integer>> commands = new HashMap<>();
-            ArrayList<Object> keepAlive = new ArrayList<>();
-
-            if (version.startsWith("3.")) {
-                // 3.x
-                if (!ExecutorRequest.MVN.equals(executorRequest.command())) {
-                    throw new IllegalArgumentException(getClass().getSimpleName() + " w/ mvn3 does not support command "
-                            + executorRequest.command());
-                }
-                // 3.9.x
-                mayAddToKeepAlive(keepAlive, cliClass, "org.fusesource.jansi.internal.JansiLoader");
-                // 3.10.x
-                mayAddToKeepAlive(keepAlive, cliClass, "org.jline.nativ.JLineNativeLoader");
-
-                Constructor<?> newMavenCli = cliClass.getConstructor(classWorld.getClass());
-                Object mavenCli = newMavenCli.newInstance(classWorld);
-                Class<?>[] parameterTypes = {String[].class, String.class, PrintStream.class, PrintStream.class};
-                Method doMain = cliClass.getMethod("doMain", parameterTypes);
-                commands.put(ExecutorRequest.MVN, r -> {
-                    System.setProperties(prepareProperties(r));
-                    try {
-                        ArrayList<String> args = new ArrayList<>(mavenArgs);
-                        args.addAll(r.arguments());
-                        PrintStream stdout = r.stdOut().isEmpty()
-                                ? null
-                                : new PrintStream(r.stdOut().orElseThrow(), true);
-                        PrintStream stderr = r.stdErr().isEmpty()
-                                ? null
-                                : new PrintStream(r.stdErr().orElseThrow(), true);
-                        return (int) doMain.invoke(mavenCli, new Object[] {
-                            args.toArray(new String[0]), r.cwd().toString(), stdout, stderr
-                        });
-                    } catch (Exception e) {
-                        throw new ExecutorException("Failed to execute", e);
-                    }
-                });
-            } else {
-                // assume 4.x
-                mayAddToKeepAlive(keepAlive, cliClass, "org.jline.nativ.JLineNativeLoader");
-                for (Map.Entry<String, String> cmdEntry : MVN4_MAIN_CLASSES.entrySet()) {
-                    Class<?> cmdClass = cliClass.getClassLoader().loadClass(cmdEntry.getValue());
-                    Method mainMethod = cmdClass.getMethod(
-                            "main",
-                            String[].class,
-                            classWorld.getClass(),
-                            InputStream.class,
-                            OutputStream.class,
-                            OutputStream.class);
-                    commands.put(cmdEntry.getKey(), r -> {
-                        System.setProperties(prepareProperties(r));
-                        try {
-                            ArrayList<String> args = new ArrayList<>(mavenArgs);
-                            args.addAll(r.arguments());
-                            return (int) mainMethod.invoke(
-                                    null,
-                                    args.toArray(new String[0]),
-                                    classWorld,
-                                    r.stdIn().orElse(null),
-                                    r.stdOut().orElse(null),
-                                    r.stdErr().orElse(null));
-                        } catch (Exception e) {
-                            throw new ExecutorException("Failed to execute", e);
-                        }
-                    });
-                }
-            }
-
-            return new Context(
-                    bootClassLoader,
-                    version,
-                    classWorld,
-                    originalClassRealmIds,
-                    cliClass.getClassLoader(),
-                    commands,
-                    keepAlive);
-        } catch (Exception e) {
-            throw new ExecutorException("Failed to create executor", e);
-        } finally {
-            Thread.currentThread().setContextClassLoader(originalClassLoader);
-            System.setProperties(originalProperties);
-        }
-    }
-
-    private boolean mayAddToKeepAlive(List<Object> keepAlive, Class<?> cliClass, String className) {
-        try {
-            keepAlive.add(cliClass.getClassLoader().loadClass(className));
-            return true;
-        } catch (ClassNotFoundException e) {
-            return false;
-        }
-    }
-
-    protected Properties prepareProperties(ExecutorRequest request) {
-        System.setProperties(null); // this "inits" them!
-
-        Properties properties = new Properties();
-        properties.putAll(System.getProperties()); // get mandatory/expected init-ed above
-
-        properties.setProperty("user.dir", request.cwd().toString());
-        properties.setProperty("user.home", request.userHomeDirectory().toString());
-
-        Path mavenHome = request.installationDirectory();
-        properties.setProperty("maven.home", mavenHome.toString());
-        properties.setProperty(
-                "maven.multiModuleProjectDirectory", request.cwd().toString());
-
-        // Maven 3.x
-        properties.setProperty(
-                "library.jansi.path", mavenHome.resolve("lib/jansi-native").toString());
-
-        // Maven 4.x
-        properties.setProperty(
-                "library.jline.path", mavenHome.resolve("lib/jline-native").toString());
-
-        if (request.jvmSystemProperties().isPresent()) {
-            properties.putAll(request.jvmSystemProperties().get());
-        }
-
-        return properties;
-    }
-
-    @Override
-    public void close() throws ExecutorException {
-        if (closed.compareAndExchange(false, true)) {
-            try {
-                ArrayList<Exception> exceptions = new ArrayList<>();
-                for (Context context : contexts.values()) {
-                    try {
-                        doClose(context);
-                    } catch (Exception e) {
-                        exceptions.add(e);
-                    }
-                }
-                if (!exceptions.isEmpty()) {
-                    ExecutorException e = new ExecutorException("Could not close cleanly");
-                    exceptions.forEach(e::addSuppressed);
-                    throw e;
-                }
-            } finally {
-                System.setProperties(originalProperties);
-            }
-        }
-    }
-
-    protected void doClose(Context context) throws ExecutorException {
-        Thread.currentThread().setContextClassLoader(context.bootClassLoader);
-        try {
-            try {
-                ((Closeable) context.classWorld).close();
-            } finally {
-                context.bootClassLoader.close();
-            }
-        } catch (Exception e) {
-            throw new ExecutorException("Failed to close cleanly", e);
-        } finally {
-            Thread.currentThread().setContextClassLoader(originalClassLoader);
-        }
-    }
-
-    protected void validate(ExecutorRequest executorRequest) throws ExecutorException {}
-
-    protected URLClassLoader createMavenBootClassLoader(Path boot, List<URL> extraClasspath) {
-        ArrayList<URL> urls = new ArrayList<>(extraClasspath);
-        try (Stream<Path> stream = Files.list(boot)) {
-            stream.filter(Files::isRegularFile)
-                    .filter(p -> p.toString().endsWith(".jar"))
-                    .forEach(f -> {
-                        try {
-                            urls.add(f.toUri().toURL());
-                        } catch (MalformedURLException e) {
-                            throw new ExecutorException("Failed to build classpath: " + f, e);
-                        }
-                    });
-        } catch (IOException e) {
-            throw new ExecutorException("Failed to build classpath: " + e, e);
-        }
-        if (urls.isEmpty()) {
-            throw new IllegalArgumentException("Invalid Maven home directory; boot is empty");
-        }
-        return new URLClassLoader(
-                urls.toArray(new URL[0]), ClassLoader.getSystemClassLoader().getParent());
-    }
-
-    protected String getMavenVersion(Class<?> clazz) throws IOException {
-        Properties props = new Properties();
-        try (InputStream is = clazz.getResourceAsStream("/META-INF/maven/org.apache.maven/maven-core/pom.properties")) {
-            if (is != null) {
-                props.load(is);
-            }
-            String version = props.getProperty("version");
-            if (version != null) {
-                return version;
-            }
-            return UNKNOWN_VERSION;
-        }
-    }
-}
diff --git a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/forked/ForkedMavenExecutor.java b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/forked/ForkedMavenExecutor.java
deleted file mode 100644
index 4671c74276..0000000000
--- a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/forked/ForkedMavenExecutor.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * 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.cling.executor.forked;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UncheckedIOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.maven.cling.executor.Executor;
-import org.apache.maven.cling.executor.ExecutorException;
-import org.apache.maven.cling.executor.ExecutorRequest;
-
-import static java.util.Objects.requireNonNull;
-import static org.apache.maven.cling.executor.ExecutorRequest.getCanonicalPath;
-
-/**
- * Forked executor implementation, that spawns a subprocess with Maven from the installation directory. Very costly
- * but provides the best isolation.
- */
-public class ForkedMavenExecutor implements Executor {
-    protected final boolean useMavenArgsEnv;
-    protected final AtomicBoolean closed;
-
-    public ForkedMavenExecutor() {
-        this(true);
-    }
-
-    public ForkedMavenExecutor(boolean useMavenArgsEnv) {
-        this.useMavenArgsEnv = useMavenArgsEnv;
-        this.closed = new AtomicBoolean(false);
-    }
-
-    @Override
-    public int execute(ExecutorRequest executorRequest) throws ExecutorException {
-        requireNonNull(executorRequest);
-        if (closed.get()) {
-            throw new ExecutorException("Executor is closed");
-        }
-        validate(executorRequest);
-
-        return doExecute(executorRequest);
-    }
-
-    @Override
-    public String mavenVersion(ExecutorRequest executorRequest) throws ExecutorException {
-        requireNonNull(executorRequest);
-        if (closed.get()) {
-            throw new ExecutorException("Executor is closed");
-        }
-        validate(executorRequest);
-        try {
-            Path cwd = Files.createTempDirectory("forked-executor-maven-version");
-            try {
-                ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-                int exitCode = execute(executorRequest.toBuilder()
-                        .cwd(cwd)
-                        .arguments(List.of("--version", "--quiet"))
-                        .stdOut(stdout)
-                        .build());
-                if (exitCode == 0) {
-                    if (stdout.size() > 0) {
-                        return stdout.toString()
-                                .replace("\n", "")
-                                .replace("\r", "")
-                                .trim();
-                    }
-                    return UNKNOWN_VERSION;
-                } else {
-                    throw new ExecutorException(
-                            "Maven version query unexpected exitCode=" + exitCode + "\nLog: " + stdout);
-                }
-            } finally {
-                Files.deleteIfExists(cwd);
-            }
-        } catch (IOException e) {
-            throw new ExecutorException("Failed to determine maven version", e);
-        }
-    }
-
-    protected void validate(ExecutorRequest executorRequest) throws ExecutorException {}
-
-    protected int doExecute(ExecutorRequest executorRequest) throws ExecutorException {
-        ArrayList<String> cmdAndArguments = new ArrayList<>();
-        cmdAndArguments.add(executorRequest
-                .installationDirectory()
-                .resolve("bin")
-                .resolve(IS_WINDOWS ? executorRequest.command() + ".cmd" : executorRequest.command())
-                .toString());
-
-        String mavenArgsEnv = System.getenv("MAVEN_ARGS");
-        if (useMavenArgsEnv && mavenArgsEnv != null && !mavenArgsEnv.isEmpty()) {
-            Arrays.stream(mavenArgsEnv.split(" "))
-                    .filter(s -> !s.trim().isEmpty())
-                    .forEach(cmdAndArguments::add);
-        }
-
-        cmdAndArguments.addAll(executorRequest.arguments());
-
-        ArrayList<String> jvmArgs = new ArrayList<>();
-        if (!executorRequest.userHomeDirectory().equals(getCanonicalPath(Paths.get(System.getProperty("user.home"))))) {
-            jvmArgs.add("-Duser.home=" + executorRequest.userHomeDirectory().toString());
-        }
-        if (executorRequest.jvmArguments().isPresent()) {
-            jvmArgs.addAll(executorRequest.jvmArguments().get());
-        }
-        if (executorRequest.jvmSystemProperties().isPresent()) {
-            jvmArgs.addAll(executorRequest.jvmSystemProperties().get().entrySet().stream()
-                    .map(e -> "-D" + e.getKey() + "=" + e.getValue())
-                    .toList());
-        }
-
-        HashMap<String, String> env = new HashMap<>();
-        if (executorRequest.environmentVariables().isPresent()) {
-            env.putAll(executorRequest.environmentVariables().get());
-        }
-        if (!jvmArgs.isEmpty()) {
-            String mavenOpts = env.getOrDefault("MAVEN_OPTS", "");
-            if (!mavenOpts.isEmpty()) {
-                mavenOpts += " ";
-            }
-            mavenOpts += String.join(" ", jvmArgs);
-            env.put("MAVEN_OPTS", mavenOpts);
-        }
-        env.remove("MAVEN_ARGS"); // we already used it if configured to do so
-
-        if (executorRequest.skipMavenRc()) {
-            env.put("MAVEN_SKIP_RC", "true");
-        }
-
-        try {
-            ProcessBuilder pb = new ProcessBuilder()
-                    .directory(executorRequest.cwd().toFile())
-                    .command(cmdAndArguments);
-            if (!env.isEmpty()) {
-                pb.environment().putAll(env);
-            }
-
-            Process process = pb.start();
-            pump(process, executorRequest).await();
-            return process.waitFor();
-        } catch (IOException e) {
-            throw new ExecutorException("IO problem while executing command: " + cmdAndArguments, e);
-        } catch (InterruptedException e) {
-            throw new ExecutorException("Interrupted while executing command: " + cmdAndArguments, e);
-        }
-    }
-
-    protected CountDownLatch pump(Process p, ExecutorRequest executorRequest) {
-        CountDownLatch latch = new CountDownLatch(3);
-        String suffix = "-pump-" + p.pid();
-        Thread stdoutPump = new Thread(() -> {
-            try {
-                OutputStream stdout = executorRequest.stdOut().orElse(OutputStream.nullOutputStream());
-                p.getInputStream().transferTo(stdout);
-                stdout.flush();
-            } catch (IOException e) {
-                throw new UncheckedIOException(e);
-            } finally {
-                latch.countDown();
-            }
-        });
-        stdoutPump.setName("stdout" + suffix);
-        stdoutPump.start();
-        Thread stderrPump = new Thread(() -> {
-            try {
-                OutputStream stderr = executorRequest.stdErr().orElse(OutputStream.nullOutputStream());
-                p.getErrorStream().transferTo(stderr);
-                stderr.flush();
-            } catch (IOException e) {
-                throw new UncheckedIOException(e);
-            } finally {
-                latch.countDown();
-            }
-        });
-        stderrPump.setName("stderr" + suffix);
-        stderrPump.start();
-        Thread stdinPump = new Thread(() -> {
-            try {
-                OutputStream in = p.getOutputStream();
-                executorRequest.stdIn().orElse(InputStream.nullInputStream()).transferTo(in);
-                in.flush();
-            } catch (IOException e) {
-                throw new UncheckedIOException(e);
-            } finally {
-                latch.countDown();
-            }
-        });
-        stdinPump.setName("stdin" + suffix);
-        stdinPump.start();
-        return latch;
-    }
-
-    @Override
-    public void close() throws ExecutorException {
-        if (closed.compareAndExchange(false, true)) {
-            // nothing yet
-        }
-    }
-}
diff --git a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/HelperImpl.java b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/HelperImpl.java
deleted file mode 100644
index d8109ba3e2..0000000000
--- a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/HelperImpl.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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.cling.executor.internal;
-
-import java.nio.file.Path;
-import java.util.HashMap;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.maven.api.annotations.Nullable;
-import org.apache.maven.cling.executor.Executor;
-import org.apache.maven.cling.executor.ExecutorException;
-import org.apache.maven.cling.executor.ExecutorHelper;
-import org.apache.maven.cling.executor.ExecutorRequest;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- * Simple router to executors, and delegate to executor tool.
- */
-public class HelperImpl implements ExecutorHelper {
-    private final Mode defaultMode;
-    private final Path installationDirectory;
-    private final Path userHomeDirectory;
-    private final HashMap<Mode, Executor> executors;
-
-    private final ConcurrentHashMap<String, String> cache;
-
-    public HelperImpl(
-            Mode defaultMode,
-            @Nullable Path installationDirectory,
-            @Nullable Path userHomeDirectory,
-            Executor embedded,
-            Executor forked) {
-        this.defaultMode = requireNonNull(defaultMode);
-        this.installationDirectory = installationDirectory != null
-                ? ExecutorRequest.getCanonicalPath(installationDirectory)
-                : ExecutorRequest.discoverInstallationDirectory();
-        this.userHomeDirectory = userHomeDirectory != null
-                ? ExecutorRequest.getCanonicalPath(userHomeDirectory)
-                : ExecutorRequest.discoverUserHomeDirectory();
-        this.executors = new HashMap<>();
-
-        this.executors.put(Mode.EMBEDDED, requireNonNull(embedded, "embedded"));
-        this.executors.put(Mode.FORKED, requireNonNull(forked, "forked"));
-        this.cache = new ConcurrentHashMap<>();
-    }
-
-    @Override
-    public Mode getDefaultMode() {
-        return defaultMode;
-    }
-
-    @Override
-    public ExecutorRequest.Builder executorRequest() {
-        return ExecutorRequest.mavenBuilder(installationDirectory).userHomeDirectory(userHomeDirectory);
-    }
-
-    @Override
-    public int execute(Mode mode, ExecutorRequest executorRequest) throws ExecutorException {
-        return getExecutor(mode, executorRequest).execute(executorRequest);
-    }
-
-    @Override
-    public String mavenVersion() {
-        return cache.computeIfAbsent("maven.version", k -> {
-            ExecutorRequest request = executorRequest().build();
-            return getExecutor(Mode.AUTO, request).mavenVersion(request);
-        });
-    }
-
-    protected Executor getExecutor(Mode mode, ExecutorRequest request) throws ExecutorException {
-        return switch (mode) {
-            case AUTO -> getExecutorByRequest(request);
-            case EMBEDDED -> executors.get(Mode.EMBEDDED);
-            case FORKED -> executors.get(Mode.FORKED);
-        };
-    }
-
-    private Executor getExecutorByRequest(ExecutorRequest request) {
-        if (request.environmentVariables().isEmpty() && request.jvmArguments().isEmpty()) {
-            return getExecutor(Mode.EMBEDDED, request);
-        } else {
-            return getExecutor(Mode.FORKED, request);
-        }
-    }
-}
diff --git a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/ToolboxTool.java b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/ToolboxTool.java
deleted file mode 100644
index 2adc21c438..0000000000
--- a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/ToolboxTool.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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.cling.executor.internal;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.stream.Collectors;
-
-import org.apache.maven.cling.executor.ExecutorException;
-import org.apache.maven.cling.executor.ExecutorHelper;
-import org.apache.maven.cling.executor.ExecutorRequest;
-import org.apache.maven.cling.executor.ExecutorTool;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- * {@link ExecutorTool} implementation based on Maveniverse Toolbox. It uses Toolbox mojos to implement all the
- * required operations.
- *
- * @see <a href="https://github.com/maveniverse/toolbox">Maveniverse Toolbox</a>
- */
-public class ToolboxTool implements ExecutorTool {
-    private static final String TOOLBOX_PREFIX = "eu.maveniverse.maven.plugins:toolbox:";
-
-    private final ExecutorHelper helper;
-    private final String toolboxVersion;
-    private final ExecutorHelper.Mode forceMode;
-
-    /**
-     * @deprecated Better specify required version yourself. This one is "cemented" to 0.13.7
-     */
-    @Deprecated
-    public ToolboxTool(ExecutorHelper helper) {
-        this(helper, "0.13.7");
-    }
-
-    public ToolboxTool(ExecutorHelper helper, String toolboxVersion) {
-        this(helper, toolboxVersion, null);
-    }
-
-    public ToolboxTool(ExecutorHelper helper, String toolboxVersion, ExecutorHelper.Mode forceMode) {
-        this.helper = requireNonNull(helper);
-        this.toolboxVersion = requireNonNull(toolboxVersion);
-        this.forceMode = forceMode; // nullable
-    }
-
-    @Override
-    public Map<String, String> dump(ExecutorRequest.Builder executorRequest) throws ExecutorException {
-        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        ByteArrayOutputStream stderr = new ByteArrayOutputStream();
-        ExecutorRequest.Builder builder = mojo(executorRequest, "gav-dump")
-                .argument("-DasProperties")
-                .stdOut(stdout)
-                .stdErr(stderr);
-        doExecute(builder);
-        try {
-            Properties properties = new Properties();
-            properties.load(new ByteArrayInputStream(
-                    validateOutput(false, stdout, stderr).getBytes()));
-            return properties.entrySet().stream()
-                    .collect(Collectors.toMap(
-                            e -> String.valueOf(e.getKey()),
-                            e -> String.valueOf(e.getValue()),
-                            (prev, next) -> next,
-                            HashMap::new));
-        } catch (IOException e) {
-            throw new ExecutorException("Unable to parse properties", e);
-        }
-    }
-
-    @Override
-    public String localRepository(ExecutorRequest.Builder executorRequest) throws ExecutorException {
-        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        ByteArrayOutputStream stderr = new ByteArrayOutputStream();
-        ExecutorRequest.Builder builder = mojo(executorRequest, "gav-local-repository-path")
-                .stdOut(stdout)
-                .stdErr(stderr);
-        doExecute(builder);
-        return validateOutput(true, stdout, stderr);
-    }
-
-    @Override
-    public String artifactPath(ExecutorRequest.Builder executorRequest, String gav, String repositoryId)
-            throws ExecutorException {
-        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        ByteArrayOutputStream stderr = new ByteArrayOutputStream();
-        ExecutorRequest.Builder builder = mojo(executorRequest, "gav-artifact-path")
-                .argument("-Dgav=" + gav)
-                .stdOut(stdout)
-                .stdErr(stderr);
-        if (repositoryId != null) {
-            builder.argument("-Drepository=" + repositoryId + "::unimportant");
-        }
-        doExecute(builder);
-        return validateOutput(true, stdout, stderr);
-    }
-
-    @Override
-    public String metadataPath(ExecutorRequest.Builder executorRequest, String gav, String repositoryId)
-            throws ExecutorException {
-        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        ByteArrayOutputStream stderr = new ByteArrayOutputStream();
-        ExecutorRequest.Builder builder = mojo(executorRequest, "gav-metadata-path")
-                .argument("-Dgav=" + gav)
-                .stdOut(stdout)
-                .stdErr(stderr);
-        if (repositoryId != null) {
-            builder.argument("-Drepository=" + repositoryId + "::unimportant");
-        }
-        doExecute(builder);
-        return validateOutput(true, stdout, stderr);
-    }
-
-    private ExecutorRequest.Builder mojo(ExecutorRequest.Builder builder, String mojo) {
-        if (helper.mavenVersion().startsWith("4.")) {
-            builder.argument("--raw-streams");
-        }
-        return builder.argument(TOOLBOX_PREFIX + toolboxVersion + ":" + mojo)
-                .argument("--quiet")
-                .argument("-DforceStdout");
-    }
-
-    private void doExecute(ExecutorRequest.Builder builder) {
-        ExecutorRequest request = builder.build();
-        int ec = forceMode == null ? helper.execute(request) : helper.execute(forceMode, request);
-        if (ec != 0) {
-            throw new ExecutorException("Unexpected exit code=" + ec + "; stdout="
-                    + request.stdOut().orElse(null) + "; stderr="
-                    + request.stdErr().orElse(null));
-        }
-    }
-
-    /**
-     * Performs "sanity check" for output, making sure no insane values like empty strings are returned.
-     */
-    private String validateOutput(boolean shave, ByteArrayOutputStream stdout, ByteArrayOutputStream stderr) {
-        String result = stdout.toString();
-        if (shave) {
-            result = result.replace("\n", "").replace("\r", "");
-        }
-        // sanity checks: stderr has any OR result is empty string (no method should emit empty string)
-        if (result.trim().isEmpty()) {
-            // see bug https://github.com/apache/maven/pull/11303 Fail in this case
-            // tl;dr We NEVER expect empty string as output from this tool; so fail here instead to chase ghosts
-            throw new IllegalStateException("Empty output from Toolbox; stdout[" + stdout.size() + "]=" + stdout
-                    + "; stderr[" + stderr.size() + "]=" + stderr);
-        }
-        return result;
-    }
-}
diff --git a/impl/maven-executor/src/site/site.xml b/impl/maven-executor/src/site/site.xml
deleted file mode 100644
index 4ee3b709cf..0000000000
--- a/impl/maven-executor/src/site/site.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?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.
--->
-
-<site xmlns="http://maven.apache.org/SITE/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/SITE/2.0.0 https://maven.apache.org/xsd/site-2.0.0.xsd">
-
-  <edit>${project.scm.url}</edit>
-
-  <body>
-    <menu name="Overview">
-      <item name="Introduction" href="index.html"/>
-      <item name="Javadocs" href="apidocs/index.html"/>
-      <item name="Source Xref" href="xref/index.html"/>
-      <!--item name="FAQ" href="faq.html"/-->
-    </menu>
-  </body>
-</site>
diff --git a/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/Environment.java b/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/Environment.java
deleted file mode 100644
index 771661a435..0000000000
--- a/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/Environment.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.cling.executor;
-
-public final class Environment {
-    private Environment() {}
-
-    public static final String TOOLBOX_VERSION = System.getProperty("version.toolbox", "UNSET version.toolbox");
-}
diff --git a/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/MavenExecutorTestSupport.java b/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/MavenExecutorTestSupport.java
deleted file mode 100644
index a2a095271c..0000000000
--- a/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/MavenExecutorTestSupport.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * 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.cling.executor;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Collection;
-import java.util.List;
-
-import eu.maveniverse.maven.mimir.testing.MimirInfuser;
-import org.apache.maven.api.annotations.Nullable;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInfo;
-import org.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.condition.DisabledOnOs;
-import org.junit.jupiter.api.io.CleanupMode;
-import org.junit.jupiter.api.io.TempDir;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.condition.OS.WINDOWS;
-
-@Timeout(60)
-public abstract class MavenExecutorTestSupport {
-    @TempDir(cleanup = CleanupMode.NEVER)
-    private static Path tempDir;
-
-    private Path cwd;
-
-    private Path userHome;
-
-    @BeforeEach
-    void beforeEach(TestInfo testInfo) throws Exception {
-        cwd = tempDir.resolve(testInfo.getTestMethod().orElseThrow().getName()).resolve("cwd");
-        Files.createDirectories(cwd.resolve(".mvn"));
-        userHome = tempDir.resolve(testInfo.getTestMethod().orElseThrow().getName())
-                .resolve("home");
-        Files.createDirectories(userHome);
-
-        System.out.println("=== " + testInfo.getTestMethod().orElseThrow().getName());
-    }
-
-    private static Executor executor;
-
-    protected final Executor createAndMemoizeExecutor() {
-        if (executor == null) {
-            executor = doSelectExecutor();
-        }
-        return executor;
-    }
-
-    @AfterAll
-    static void afterAll() {
-        if (executor != null) {
-            executor.close();
-            executor = null;
-        }
-    }
-
-    protected abstract Executor doSelectExecutor();
-
-    @Test
-    void mvnenc4() throws Exception {
-        String logfile = "m4.log";
-        execute(
-                cwd.resolve(logfile),
-                List.of(mvn4ExecutorRequestBuilder()
-                        .command("mvnenc")
-                        .cwd(cwd)
-                        .userHomeDirectory(userHome)
-                        .argument("diag")
-                        .argument("-l")
-                        .argument(logfile)
-                        .build()));
-        System.out.println(Files.readString(cwd.resolve(logfile)));
-    }
-
-    @DisabledOnOs(
-            value = WINDOWS,
-            disabledReason = "JUnit on Windows fails to clean up as mvn3 does not close log file properly")
-    @Test
-    void dump3() throws Exception {
-        String logfile = "m3.log";
-        execute(
-                cwd.resolve(logfile),
-                List.of(mvn3ExecutorRequestBuilder()
-                        .cwd(cwd)
-                        .userHomeDirectory(userHome)
-                        .argument("eu.maveniverse.maven.plugins:toolbox:" + Environment.TOOLBOX_VERSION + ":gav-dump")
-                        .argument("-l")
-                        .argument(logfile)
-                        .build()));
-        System.out.println(Files.readString(cwd.resolve(logfile)));
-    }
-
-    @Test
-    void dump4() throws Exception {
-        String logfile = "m4.log";
-        execute(
-                cwd.resolve(logfile),
-                List.of(mvn4ExecutorRequestBuilder()
-                        .cwd(cwd)
-                        .userHomeDirectory(userHome)
-                        .argument("eu.maveniverse.maven.plugins:toolbox:" + Environment.TOOLBOX_VERSION + ":gav-dump")
-                        .argument("-l")
-                        .argument(logfile)
-                        .build()));
-        System.out.println(Files.readString(cwd.resolve(logfile)));
-    }
-
-    @DisabledOnOs(
-            value = WINDOWS,
-            disabledReason = "JUnit on Windows fails to clean up as mvn3 does not close log file properly")
-    @Test
-    void defaultFs3() throws Exception {
-        layDownFiles(cwd);
-        String logfile = "m3.log";
-        execute(
-                cwd.resolve(logfile),
-                List.of(mvn3ExecutorRequestBuilder()
-                        .cwd(cwd)
-                        .argument("-V")
-                        .argument("verify")
-                        .argument("-l")
-                        .argument(logfile)
-                        .build()));
-        System.out.println(Files.readString(cwd.resolve(logfile)));
-    }
-
-    @Test
-    void defaultFs4() throws Exception {
-        layDownFiles(cwd);
-        String logfile = "m4.log";
-        execute(
-                cwd.resolve(logfile),
-                List.of(mvn4ExecutorRequestBuilder()
-                        .cwd(cwd)
-                        .argument("-V")
-                        .argument("verify")
-                        .argument("-l")
-                        .argument(logfile)
-                        .build()));
-        System.out.println(Files.readString(cwd.resolve(logfile)));
-    }
-
-    @Test
-    void version3() throws Exception {
-        assertEquals(
-                System.getProperty("maven3version"),
-                mavenVersion(mvn3ExecutorRequestBuilder().build()));
-    }
-
-    @Test
-    void version4() throws Exception {
-        assertEquals(
-                System.getProperty("maven4version"),
-                mavenVersion(mvn4ExecutorRequestBuilder().build()));
-    }
-
-    @Test
-    void defaultFs4CaptureOutput() throws Exception {
-        layDownFiles(cwd);
-        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        execute(
-                null,
-                List.of(mvn4ExecutorRequestBuilder()
-                        .cwd(cwd)
-                        .argument("-V")
-                        .argument("verify")
-                        .stdOut(stdout)
-                        .build()));
-        System.out.println(stdout);
-        assertFalse(stdout.toString().contains("[\u001B["), "By default no ANSI color codes");
-        assertTrue(stdout.toString().contains("INFO"), "No INFO found");
-    }
-
-    @Test
-    void defaultFs4CaptureOutputWithForcedColor() throws Exception {
-        layDownFiles(cwd);
-        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        execute(
-                null,
-                List.of(mvn4ExecutorRequestBuilder()
-                        .cwd(cwd)
-                        .argument("-V")
-                        .argument("verify")
-                        .argument("--color=yes")
-                        .stdOut(stdout)
-                        .build()));
-        System.out.println(stdout);
-        assertTrue(stdout.toString().contains("[\u001B["), "No ANSI codes present");
-        assertTrue(stdout.toString().contains("INFO"), "No INFO found");
-    }
-
-    @Test
-    void defaultFs4CaptureOutputWithForcedOffColor() throws Exception {
-        layDownFiles(cwd);
-        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        execute(
-                null,
-                List.of(mvn4ExecutorRequestBuilder()
-                        .cwd(cwd)
-                        .argument("-V")
-                        .argument("verify")
-                        .argument("--color=no")
-                        .stdOut(stdout)
-                        .build()));
-        System.out.println(stdout);
-        assertFalse(stdout.toString().contains("[\u001B["), "No ANSI codes present");
-        assertTrue(stdout.toString().contains("INFO"), "No INFO found");
-    }
-
-    @Test
-    void defaultFs3CaptureOutput() throws Exception {
-        layDownFiles(cwd);
-        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        execute(
-                null,
-                List.of(mvn3ExecutorRequestBuilder()
-                        .cwd(cwd)
-                        .argument("-V")
-                        .argument("verify")
-                        .stdOut(stdout)
-                        .build()));
-        System.out.println(stdout);
-        // Note: we do not validate ANSI as Maven3 is weird in this respect (thinks is color but is not)
-        // assertTrue(stdout.toString().contains("[\u001B["), "No ANSI codes present");
-        assertTrue(stdout.toString().contains("INFO"), "No INFO found");
-    }
-
-    @Test
-    void defaultFs3CaptureOutputWithForcedColor() throws Exception {
-        layDownFiles(cwd);
-        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        execute(
-                null,
-                List.of(mvn3ExecutorRequestBuilder()
-                        .cwd(cwd)
-                        .argument("-V")
-                        .argument("verify")
-                        .argument("--color=yes")
-                        .stdOut(stdout)
-                        .build()));
-        System.out.println(stdout);
-        assertTrue(stdout.toString().contains("[\u001B["), "No ANSI codes present");
-        assertTrue(stdout.toString().contains("INFO"), "No INFO found");
-    }
-
-    @Test
-    void defaultFs3CaptureOutputWithForcedOffColor() throws Exception {
-        layDownFiles(cwd);
-        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        execute(
-                null,
-                List.of(mvn3ExecutorRequestBuilder()
-                        .cwd(cwd)
-                        .argument("-V")
-                        .argument("verify")
-                        .argument("--color=no")
-                        .stdOut(stdout)
-                        .build()));
-        System.out.println(stdout);
-        assertFalse(stdout.toString().contains("[\u001B["), "No ANSI codes present");
-        assertTrue(stdout.toString().contains("INFO"), "No INFO found");
-    }
-
-    public static final String POM_STRING = """
-                <?xml version="1.0" encoding="UTF-8"?>
-                <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 https://maven.apache.org/maven-v4_0_0.xsd">
-
-                    <modelVersion>4.0.0</modelVersion>
-
-                    <groupId>org.apache.maven.samples</groupId>
-                    <artifactId>sample</artifactId>
-                    <version>1.0.0</version>
-
-                    <dependencyManagement>
-                      <dependencies>
-                        <dependency>
-                          <groupId>org.junit</groupId>
-                          <artifactId>junit-bom</artifactId>
-                          <version>5.11.1</version>
-                          <type>pom</type>
-                          <scope>import</scope>
-                        </dependency>
-                      </dependencies>
-                    </dependencyManagement>
-
-                    <dependencies>
-                      <dependency>
-                        <groupId>org.junit.jupiter</groupId>
-                        <artifactId>junit-jupiter-api</artifactId>
-                        <scope>test</scope>
-                      </dependency>
-                    </dependencies>
-
-                </project>
-                """;
-
-    public static final String APP_JAVA_STRING = """
-            package org.apache.maven.samples.sample;
-
-            public class App {
-                public static void main(String... args) {
-                    System.out.println("Hello World!");
-                }
-            }
-            """;
-
-    protected void execute(@Nullable Path logFile, Collection<ExecutorRequest> requests) throws Exception {
-        Executor invoker = createAndMemoizeExecutor();
-        for (ExecutorRequest request : requests) {
-            if (MimirInfuser.isMimirPresentUW()) {
-                if (maven3Home().equals(request.installationDirectory())) {
-                    MimirInfuser.doInfusePW(request.cwd(), request.userHomeDirectory());
-                } else if (maven4Home().equals(request.installationDirectory())) {
-                    MimirInfuser.doInfuseUW(request.userHomeDirectory());
-                }
-                MimirInfuser.preseedItselfIntoInnerUserHome(request.userHomeDirectory());
-            }
-            int exitCode = invoker.execute(request);
-            if (exitCode != 0) {
-                throw new FailedExecution(request, exitCode, logFile == null ? "" : Files.readString(logFile));
-            }
-        }
-    }
-
-    protected String mavenVersion(ExecutorRequest request) throws Exception {
-        return createAndMemoizeExecutor().mavenVersion(request);
-    }
-
-    public ExecutorRequest.Builder mvn3ExecutorRequestBuilder() {
-        return customize(ExecutorRequest.mavenBuilder(maven3Home()));
-    }
-
-    private Path maven3Home() {
-        return ExecutorRequest.getCanonicalPath(Paths.get(System.getProperty("maven3home")));
-    }
-
-    public ExecutorRequest.Builder mvn4ExecutorRequestBuilder() {
-        return customize(ExecutorRequest.mavenBuilder(maven4Home()));
-    }
-
-    private Path maven4Home() {
-        return ExecutorRequest.getCanonicalPath(Paths.get(System.getProperty("maven4home")));
-    }
-
-    private ExecutorRequest.Builder customize(ExecutorRequest.Builder builder) {
-        builder =
-                builder.cwd(cwd).userHomeDirectory(userHome).argument("-Daether.remoteRepositoryFilter.prefixes=false");
-        if (System.getProperty("localRepository") != null) {
-            builder.argument("-Dmaven.repo.local.tail=" + System.getProperty("localRepository"));
-        }
-        return builder;
-    }
-
-    protected void layDownFiles(Path cwd) throws IOException {
-        Path pom = cwd.resolve("pom.xml").toAbsolutePath();
-        Files.writeString(pom, POM_STRING);
-        Path appJava = cwd.resolve("src/main/java/org/apache/maven/samples/sample/App.java");
-        Files.createDirectories(appJava.getParent());
-        Files.writeString(appJava, APP_JAVA_STRING);
-    }
-
-    protected static class FailedExecution extends Exception {
-        private final ExecutorRequest request;
-        private final int exitCode;
-        private final String log;
-
-        public FailedExecution(ExecutorRequest request, int exitCode, String log) {
-            super(request.toString() + " => " + exitCode + "\n" + log);
-            this.request = request;
-            this.exitCode = exitCode;
-            this.log = log;
-        }
-
-        public ExecutorRequest getRequest() {
-            return request;
-        }
-
-        public int getExitCode() {
-            return exitCode;
-        }
-
-        public String getLog() {
-            return log;
-        }
-    }
-}
diff --git a/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/embedded/EmbeddedMavenExecutorTest.java b/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/embedded/EmbeddedMavenExecutorTest.java
deleted file mode 100644
index 6433235b69..0000000000
--- a/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/embedded/EmbeddedMavenExecutorTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.cling.executor.embedded;
-
-import org.apache.maven.cling.executor.Executor;
-import org.apache.maven.cling.executor.MavenExecutorTestSupport;
-
-/**
- * Embedded executor UT
- */
-public class EmbeddedMavenExecutorTest extends MavenExecutorTestSupport {
-
-    @Override
-    protected Executor doSelectExecutor() {
-        return new EmbeddedMavenExecutor();
-    }
-}
diff --git a/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/forked/ForkedMavenExecutorTest.java b/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/forked/ForkedMavenExecutorTest.java
deleted file mode 100644
index a1f4362eac..0000000000
--- a/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/forked/ForkedMavenExecutorTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.cling.executor.forked;
-
-import org.apache.maven.cling.executor.Executor;
-import org.apache.maven.cling.executor.MavenExecutorTestSupport;
-
-/**
- * Forked executor UT
- */
-public class ForkedMavenExecutorTest extends MavenExecutorTestSupport {
-
-    @Override
-    protected Executor doSelectExecutor() {
-        return new ForkedMavenExecutor();
-    }
-}
diff --git a/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/impl/ToolboxToolTest.java b/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/impl/ToolboxToolTest.java
deleted file mode 100644
index fc85626824..0000000000
--- a/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/impl/ToolboxToolTest.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * 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.cling.executor.impl;
-
-import java.io.File;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Map;
-
-import eu.maveniverse.maven.mimir.testing.MimirInfuser;
-import org.apache.maven.cling.executor.Environment;
-import org.apache.maven.cling.executor.Executor;
-import org.apache.maven.cling.executor.ExecutorHelper;
-import org.apache.maven.cling.executor.ExecutorRequest;
-import org.apache.maven.cling.executor.embedded.EmbeddedMavenExecutor;
-import org.apache.maven.cling.executor.forked.ForkedMavenExecutor;
-import org.apache.maven.cling.executor.internal.HelperImpl;
-import org.apache.maven.cling.executor.internal.ToolboxTool;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.TestInfo;
-import org.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.io.CleanupMode;
-import org.junit.jupiter.api.io.TempDir;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.EnumSource;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-@Timeout(60)
-public class ToolboxToolTest {
-    private static final Executor EMBEDDED_MAVEN_EXECUTOR = new EmbeddedMavenExecutor();
-    private static final Executor FORKED_MAVEN_EXECUTOR = new ForkedMavenExecutor();
-
-    @TempDir(cleanup = CleanupMode.NEVER)
-    private static Path tempDir;
-
-    private Path userHome;
-    private Path cwd;
-
-    @BeforeEach
-    void beforeEach(TestInfo testInfo) throws Exception {
-        String testName = testInfo.getTestMethod().orElseThrow().getName();
-        userHome = tempDir.resolve(testName);
-        cwd = userHome.resolve("cwd");
-        Files.createDirectories(cwd.resolve(".mvn"));
-
-        if (MimirInfuser.isMimirPresentUW()) {
-            if (testName.contains("3")) {
-                MimirInfuser.doInfusePW(cwd, userHome);
-            } else {
-                MimirInfuser.doInfuseUW(userHome);
-            }
-            MimirInfuser.preseedItselfIntoInnerUserHome(userHome);
-        }
-
-        System.out.println("=== " + testInfo.getTestMethod().orElseThrow().getName());
-    }
-
-    private ExecutorRequest.Builder getExecutorRequest(ExecutorHelper helper) {
-        ExecutorRequest.Builder builder =
-                helper.executorRequest().cwd(cwd).argument("-Daether.remoteRepositoryFilter.prefixes=false");
-        if (System.getProperty("localRepository") != null) {
-            builder.argument("-Dmaven.repo.local.tail=" + System.getProperty("localRepository"));
-        }
-        return builder;
-    }
-
-    @ParameterizedTest
-    @EnumSource(ExecutorHelper.Mode.class)
-    void dump3(ExecutorHelper.Mode mode) throws Exception {
-        ExecutorHelper helper =
-                new HelperImpl(mode, mvn3Home(), userHome, EMBEDDED_MAVEN_EXECUTOR, FORKED_MAVEN_EXECUTOR);
-        Map<String, String> dump =
-                new ToolboxTool(helper, Environment.TOOLBOX_VERSION).dump(getExecutorRequest(helper));
-        System.out.println(mode.name() + ": " + dump.toString());
-        assertEquals(System.getProperty("maven3version"), dump.get("maven.version"));
-    }
-
-    @ParameterizedTest
-    @EnumSource(ExecutorHelper.Mode.class)
-    void dump4(ExecutorHelper.Mode mode) throws Exception {
-        ExecutorHelper helper =
-                new HelperImpl(mode, mvn4Home(), userHome, EMBEDDED_MAVEN_EXECUTOR, FORKED_MAVEN_EXECUTOR);
-        Map<String, String> dump =
-                new ToolboxTool(helper, Environment.TOOLBOX_VERSION).dump(getExecutorRequest(helper));
-        System.out.println(mode.name() + ": " + dump.toString());
-        assertEquals(System.getProperty("maven4version"), dump.get("maven.version"));
-    }
-
-    @ParameterizedTest
-    @EnumSource(ExecutorHelper.Mode.class)
-    void version3(ExecutorHelper.Mode mode) {
-        ExecutorHelper helper =
-                new HelperImpl(mode, mvn3Home(), userHome, EMBEDDED_MAVEN_EXECUTOR, FORKED_MAVEN_EXECUTOR);
-        System.out.println(mode.name() + ": " + helper.mavenVersion());
-        assertEquals(System.getProperty("maven3version"), helper.mavenVersion());
-    }
-
-    @ParameterizedTest
-    @EnumSource(ExecutorHelper.Mode.class)
-    void version4(ExecutorHelper.Mode mode) {
-        ExecutorHelper helper =
-                new HelperImpl(mode, mvn4Home(), userHome, EMBEDDED_MAVEN_EXECUTOR, FORKED_MAVEN_EXECUTOR);
-        System.out.println(mode.name() + ": " + helper.mavenVersion());
-        assertEquals(System.getProperty("maven4version"), helper.mavenVersion());
-    }
-
-    @ParameterizedTest
-    @EnumSource(ExecutorHelper.Mode.class)
-    void localRepository3(ExecutorHelper.Mode mode) {
-        ExecutorHelper helper =
-                new HelperImpl(mode, mvn3Home(), userHome, EMBEDDED_MAVEN_EXECUTOR, FORKED_MAVEN_EXECUTOR);
-        String localRepository =
-                new ToolboxTool(helper, Environment.TOOLBOX_VERSION).localRepository(getExecutorRequest(helper));
-        System.out.println(mode.name() + ": " + localRepository);
-        Path local = Paths.get(localRepository);
-        assertTrue(Files.isDirectory(local));
-    }
-
-    @ParameterizedTest
-    @EnumSource(ExecutorHelper.Mode.class)
-    void localRepository4(ExecutorHelper.Mode mode) {
-        ExecutorHelper helper =
-                new HelperImpl(mode, mvn4Home(), userHome, EMBEDDED_MAVEN_EXECUTOR, FORKED_MAVEN_EXECUTOR);
-        String localRepository =
-                new ToolboxTool(helper, Environment.TOOLBOX_VERSION).localRepository(getExecutorRequest(helper));
-        System.out.println(mode.name() + ": " + localRepository);
-        Path local = Paths.get(localRepository);
-        assertTrue(Files.isDirectory(local));
-    }
-
-    @ParameterizedTest
-    @EnumSource(ExecutorHelper.Mode.class)
-    void artifactPath3(ExecutorHelper.Mode mode) {
-        ExecutorHelper helper =
-                new HelperImpl(mode, mvn3Home(), userHome, EMBEDDED_MAVEN_EXECUTOR, FORKED_MAVEN_EXECUTOR);
-        String path = new ToolboxTool(helper, Environment.TOOLBOX_VERSION)
-                .artifactPath(getExecutorRequest(helper), "aopalliance:aopalliance:1.0", "central");
-        System.out.println(mode.name() + ": " + path);
-        // split repository: assert "ends with" as split may introduce prefixes
-        assertTrue(
-                path.endsWith("aopalliance" + File.separator + "aopalliance" + File.separator + "1.0" + File.separator
-                        + "aopalliance-1.0.jar"),
-                "path=" + path);
-    }
-
-    @ParameterizedTest
-    @EnumSource(ExecutorHelper.Mode.class)
-    void artifactPath4(ExecutorHelper.Mode mode) {
-        ExecutorHelper helper =
-                new HelperImpl(mode, mvn4Home(), userHome, EMBEDDED_MAVEN_EXECUTOR, FORKED_MAVEN_EXECUTOR);
-        String path = new ToolboxTool(helper, Environment.TOOLBOX_VERSION)
-                .artifactPath(getExecutorRequest(helper), "aopalliance:aopalliance:1.0", "central");
-        System.out.println(mode.name() + ": " + path);
-        // split repository: assert "ends with" as split may introduce prefixes
-        assertTrue(
-                path.endsWith("aopalliance" + File.separator + "aopalliance" + File.separator + "1.0" + File.separator
-                        + "aopalliance-1.0.jar"),
-                "path=" + path);
-    }
-
-    @ParameterizedTest
-    @EnumSource(ExecutorHelper.Mode.class)
-    void metadataPath3(ExecutorHelper.Mode mode) {
-        ExecutorHelper helper =
-                new HelperImpl(mode, mvn4Home(), userHome, EMBEDDED_MAVEN_EXECUTOR, FORKED_MAVEN_EXECUTOR);
-        String path = new ToolboxTool(helper, Environment.TOOLBOX_VERSION)
-                .metadataPath(getExecutorRequest(helper), "aopalliance", "someremote");
-        System.out.println(mode.name() + ": " + path);
-        // split repository: assert "ends with" as split may introduce prefixes
-        assertTrue(path.endsWith("aopalliance" + File.separator + "maven-metadata-someremote.xml"), "path=" + path);
-    }
-
-    @ParameterizedTest
-    @EnumSource(ExecutorHelper.Mode.class)
-    void metadataPath4(ExecutorHelper.Mode mode) {
-        ExecutorHelper helper =
-                new HelperImpl(mode, mvn4Home(), userHome, EMBEDDED_MAVEN_EXECUTOR, FORKED_MAVEN_EXECUTOR);
-        String path = new ToolboxTool(helper, Environment.TOOLBOX_VERSION)
-                .metadataPath(getExecutorRequest(helper), "aopalliance", "someremote");
-        System.out.println(mode.name() + ": " + path);
-        // split repository: assert "ends with" as split may introduce prefixes
-        assertTrue(path.endsWith("aopalliance" + File.separator + "maven-metadata-someremote.xml"), "path=" + path);
-    }
-
-    public Path mvn3Home() {
-        return Paths.get(System.getProperty("maven3home"));
-    }
-
-    public Path mvn4Home() {
-        return Paths.get(System.getProperty("maven4home"));
-    }
-}
diff --git a/impl/pom.xml b/impl/pom.xml
index df83a63a01..b41717c555 100644
--- a/impl/pom.xml
+++ b/impl/pom.xml
@@ -40,7 +40,6 @@ under the License.
     <module>maven-core</module>
     <module>maven-cli</module>
     <module>maven-testing</module>
-    <module>maven-executor</module>
   </modules>
 
   <properties>
diff --git a/its/core-it-support/maven-it-helper/pom.xml b/its/core-it-support/maven-it-helper/pom.xml
index 960eb651e3..2e9fc52736 100644
--- a/its/core-it-support/maven-it-helper/pom.xml
+++ b/its/core-it-support/maven-it-helper/pom.xml
@@ -32,7 +32,7 @@ under the License.
 
   <dependencies>
     <dependency>
-      <groupId>org.apache.maven</groupId>
+      <groupId>org.apache.maven.executor</groupId>
       <artifactId>maven-executor</artifactId>
       <!-- Version inherited from parent dependency management -->
     </dependency>
diff --git a/its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it/Verifier.java b/its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it/Verifier.java
index c0f29a2b3d..20b784a617 100644
--- a/its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it/Verifier.java
+++ b/its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it/Verifier.java
@@ -45,14 +45,15 @@
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import org.apache.maven.cling.executor.ExecutorException;
-import org.apache.maven.cling.executor.ExecutorRequest;
-import org.apache.maven.cling.executor.ExecutorHelper;
-import org.apache.maven.cling.executor.ExecutorTool;
-import org.apache.maven.cling.executor.embedded.EmbeddedMavenExecutor;
-import org.apache.maven.cling.executor.forked.ForkedMavenExecutor;
-import org.apache.maven.cling.executor.internal.HelperImpl;
-import org.apache.maven.cling.executor.internal.ToolboxTool;
+import org.apache.maven.executor.Executor;
+import org.apache.maven.executor.ExecutorException;
+import org.apache.maven.executor.ExecutorRequest;
+import org.apache.maven.executor.ExecutorHelper;
+import org.apache.maven.executor.ExecutorResult;
+import org.apache.maven.executor.ExecutorTool;
+import org.apache.maven.executor.embedded.EmbeddedMavenExecutor;
+import org.apache.maven.executor.forked.ForkedMavenExecutor;
+import org.apache.maven.executor.support.ToolboxExecutorTool;
 import org.codehaus.plexus.util.FileUtils;
 import org.codehaus.plexus.util.StringUtils;
 
@@ -62,17 +63,21 @@
  *
  */
 public class Verifier {
+    /**
+     * The Maven home/installation directory we are testing/executing with Executor.
+     */
+    private static final Path MAVEN_HOME = Paths.get(System.getProperty("maven.home"));
     /**
      * Keep executor alive, as long as Verifier is in classloader. Embedded classloader keeps embedded Maven
      * ClassWorld alive, instead to re-create it per invocation, making embedded execution fast(er).
+     *  Points to test subjected Maven home.
      */
-    private static final EmbeddedMavenExecutor EMBEDDED_MAVEN_EXECUTOR = new EmbeddedMavenExecutor();
+    private static final EmbeddedMavenExecutor EMBEDDED_MAVEN_EXECUTOR = new EmbeddedMavenExecutor(MAVEN_HOME);
     /**
      * Keep executor alive, as long as Verifier is in classloader. For forked this means nothing, but is
-     * at least "handled the same" as embedded counterpart. Later on, we could have some similar solution like
-     * mvnd has, and keep pool of "hot" processes maybe?
+     * at least "handled the same" as embedded counterpart. Points to test subjected Maven home.
      */
-    private static final ForkedMavenExecutor FORKED_MAVEN_EXECUTOR = new ForkedMavenExecutor();
+    private static final ForkedMavenExecutor FORKED_MAVEN_EXECUTOR = new ForkedMavenExecutor(MAVEN_HOME);
 
     /**
      * The "preferred" fork mode of Verifier, defaults to "auto". In fact, am unsure is any other fork mode usable,
@@ -164,13 +169,11 @@ public Verifier(String basedir, List<String> defaultCliArguments, boolean create
             this.userHomeDirectory = Paths.get(System.getProperty("maven.test.user.home", "user.home"));
             Files.createDirectories(this.userHomeDirectory);
             this.outerLocalRepository = Paths.get(System.getProperty("maven.test.repo.outer", ".m2/repository"));
-            this.executorHelper = new HelperImpl(
+            this.executorHelper = ExecutorHelper.forExecutors(
                     VERIFIER_FORK_MODE,
-                    Paths.get(System.getProperty("maven.home")),
-                    this.userHomeDirectory,
                     EMBEDDED_MAVEN_EXECUTOR,
                     FORKED_MAVEN_EXECUTOR);
-            this.executorTool = new ToolboxTool(executorHelper, toolboxVersion);
+            this.executorTool = new ToolboxExecutorTool(executorHelper, toolboxVersion);
             this.defaultCliArguments =
                     new ArrayList<>(defaultCliArguments != null ? defaultCliArguments : DEFAULT_CLI_ARGUMENTS);
             this.logFile = this.basedir.resolve(logFileName);
@@ -248,11 +251,9 @@ public void execute() throws VerificationException {
         args.add("-Daether.remoteRepositoryFilter.prefixes=false");
 
         try {
-            ExecutorRequest.Builder builder = executorHelper
-                    .executorRequest()
+            ExecutorRequest.Builder builder = executorRequest()
                     .command(executable)
                     .cwd(basedir)
-                    .userHomeDirectory(userHomeDirectory)
                     .jvmArguments(jvmArguments)
                     .arguments(args)
                     .skipMavenRc(skipMavenRc);
@@ -283,7 +284,7 @@ public void execute() throws VerificationException {
                 }
             }
 
-            int ret = executorHelper.execute(mode, request);
+            ExecutorResult result = executorHelper.execute(mode, request);
 
             // After execution, prepend the command line to the log file
             if (commandLineHeader != null && Files.exists(logFile)) {
@@ -320,14 +321,14 @@ public void execute() throws VerificationException {
                 }
             }
 
-            if (ret > 0) {
+            if (!result.success()) {
                 String dump;
                 try {
                     dump = executorTool.dump(request.toBuilder()).toString();
                 } catch (Exception e) {
                     dump = "FAILED: " + e.getMessage();
                 }
-                throw new VerificationException("Exit code was non-zero: " + ret + "; command line and log = \n"
+                throw new VerificationException("Exit code was non-zero: " + result.exitCode().orElse(-1) + "; command line and log = \n"
                         + getExecutable() + " "
                         + "\nstdout: " + stdout
                         + "\nstderr: " + stderr
@@ -442,10 +443,8 @@ public String getLocalRepositoryWithSettings(String settingsXml) {
             if (!Files.isRegularFile(settingsFile)) {
                 throw new IllegalArgumentException("settings xml does not exist: " + settingsXml);
             }
-            return executorTool.localRepository(executorHelper
-                    .executorRequest()
+            return executorTool.localRepository(executorRequest()
                     .cwd(tempBasedir)
-                    .userHomeDirectory(userHomeDirectory)
                     .argument("-s")
                     .argument(settingsFile.toString()));
         } else {
@@ -454,7 +453,7 @@ public String getLocalRepositoryWithSettings(String settingsXml) {
                 return outerHead;
             } else {
                 return executorTool.localRepository(
-                        executorHelper.executorRequest().cwd(tempBasedir).userHomeDirectory(userHomeDirectory));
+                        executorRequest().cwd(tempBasedir));
             }
         }
     }
@@ -476,12 +475,12 @@ private String formatCommandLine(ExecutorRequest request, ExecutorHelper.Mode mo
 
         cmdLine.append("# Command line: ");
         // Add the Maven executable path
-        Path mavenExecutable = request.installationDirectory()
+        Path mavenExecutable = MAVEN_HOME
                 .resolve("bin")
-                .resolve(System.getProperty("os.name").toLowerCase().contains("windows")
+                .resolve(Executor.IS_WINDOWS
                     ? request.command() + ".cmd"
                     : request.command());
-        cmdLine.append(mavenExecutable.toString());
+        cmdLine.append(mavenExecutable);
 
         // Add MAVEN_ARGS if they would be used (only for forked mode)
         if (mode == ExecutorHelper.Mode.FORKED || mode == ExecutorHelper.Mode.AUTO) {
@@ -865,7 +864,11 @@ public String getArtifactPath(String gid, String aid, String version, String ext
         }
         return getLocalRepository()
                 + File.separator
-                + executorTool.artifactPath(executorHelper.executorRequest(), gav, null);
+                + executorTool.artifactPath(executorRequest(), gav, null);
+    }
+
+    private ExecutorRequest.Builder executorRequest() {
+        return ExecutorRequest.mavenBuilder().userHomeDirectory(userHomeDirectory);
     }
 
     private String getSupportArtifactPath(String artifact) {
@@ -923,7 +926,7 @@ public String getSupportArtifactPath(String gid, String aid, String version, Str
         }
         return outerLocalRepository
                 .resolve(executorTool.artifactPath(
-                        executorHelper.executorRequest().argument("-Dmaven.repo.local=" + outerLocalRepository),
+                        executorRequest().argument("-Dmaven.repo.local=" + outerLocalRepository),
                         gav,
                         null))
                 .toString();
@@ -997,7 +1000,7 @@ public String getArtifactMetadataPath(String gid, String aid, String version, St
         gav += filename;
         return getLocalRepository()
                 + File.separator
-                + executorTool.metadataPath(executorHelper.executorRequest(), gav, repoId);
+                + executorTool.metadataPath(executorRequest(), gav, repoId);
     }
 
     /**
@@ -1027,7 +1030,7 @@ public void deleteArtifact(String org, String name, String version, String ext)
      * @since 1.2
      */
     public void deleteArtifacts(String gid) throws IOException {
-        String mdPath = executorTool.metadataPath(executorHelper.executorRequest(), gid, null);
+        String mdPath = executorTool.metadataPath(executorRequest(), gid, null);
         Path dir = Paths.get(getLocalRepository()).resolve(mdPath).getParent();
         FileUtils.deleteDirectory(dir.toFile());
     }
@@ -1047,7 +1050,7 @@ public void deleteArtifacts(String gid, String aid, String version) throws IOExc
         requireNonNull(version, "version is null");
 
         String mdPath =
-                executorTool.metadataPath(executorHelper.executorRequest(), gid + ":" + aid + ":" + version, null);
+                executorTool.metadataPath(executorRequest(), gid + ":" + aid + ":" + version, null);
         Path dir = Paths.get(getLocalRepository()).resolve(mdPath).getParent();
         FileUtils.deleteDirectory(dir.toFile());
     }
diff --git a/its/pom.xml b/its/pom.xml
index 750ef41466..923aec65d9 100644
--- a/its/pom.xml
+++ b/its/pom.xml
@@ -263,10 +263,11 @@ under the License.
         <artifactId>maven-compat</artifactId>
         <version>${maven-version}</version>
       </dependency>
+
       <dependency>
-        <groupId>org.apache.maven</groupId>
+        <groupId>org.apache.maven.executor</groupId>
         <artifactId>maven-executor</artifactId>
-        <version>${maven-version}</version>
+        <version>1.0.0-SNAPSHOT</version>
       </dependency>
 
       <dependency>