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

gnodet 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 5b77395cfd [MNG-8558] Switch toolchain support for v4 API (#2084)
5b77395cfd is described below

commit 5b77395cfd082a848792b9ed127440ab5e0b28c2
Author: Guillaume Nodet <[email protected]>
AuthorDate: Tue Feb 11 13:33:57 2025 +0100

    [MNG-8558] Switch toolchain support for v4 API (#2084)
---
 .../main/java/org/apache/maven/api/Session.java    |   9 +
 .../main/java/org/apache/maven/api/Toolchain.java  |   8 +
 .../maven/api/services/ToolchainFactory.java       |  29 ++-
 .../api/services/ToolchainFactoryException.java    |  16 +-
 .../maven/api/services/ToolchainManager.java       |  55 +++--
 .../apache/maven/toolchain/DefaultToolchain.java   |   0
 .../maven/toolchain/DefaultToolchainManager.java   | 181 ++++++++++++++
 .../toolchain/MisconfiguredToolchainException.java |   0
 .../apache/maven/toolchain/RequirementMatcher.java |   0
 .../maven/toolchain/RequirementMatcherFactory.java |   0
 .../java/org/apache/maven/toolchain/Toolchain.java |   0
 .../apache/maven/toolchain/ToolchainFactory.java   |   0
 .../apache/maven/toolchain/ToolchainManager.java   |   0
 .../maven/toolchain/ToolchainManagerPrivate.java   |   0
 .../apache/maven/toolchain/ToolchainPrivate.java   |   0
 .../maven/toolchain/java/DefaultJavaToolChain.java |   0
 .../apache/maven/toolchain/java/JavaToolchain.java |   0
 .../maven/toolchain/java/JavaToolchainFactory.java |   0
 .../maven/toolchain/java/JavaToolchainImpl.java    |   0
 .../toolchain/DefaultToolchainManagerTest.java     | 264 +++++++++++++++++++++
 .../maven/toolchain/DefaultToolchainTest.java      |   0
 .../toolchain/RequirementMatcherFactoryTest.java   |   0
 impl/maven-cli/pom.xml                             |   5 +
 .../apache/maven/cling/invoker/LookupContext.java  |   2 +
 .../maven/cling/invoker/mvn/MavenInvoker.java      |  18 +-
 impl/maven-core/pom.xml                            |  13 +-
 .../apache/maven/internal/impl/DefaultSession.java |  11 +
 .../internal/impl/DefaultToolchainManager.java     | 117 ---------
 .../maven/toolchain/DefaultToolchainManager.java   | 135 -----------
 .../toolchain/DefaultToolchainManagerPrivate.java  |  88 -------
 .../org/apache/maven/internal/impl/TestApi.java    |   6 +-
 .../DefaultToolchainManagerPrivateTest.java        | 152 ------------
 .../toolchain/DefaultToolchainManagerTest.java     | 146 ------------
 .../apache/maven/impl/DefaultToolchainManager.java | 127 ++++++++++
 .../maven/impl/model/DefaultModelBuilder.java      |   2 +-
 .../maven/impl/model/DefaultModelProcessor.java    |   3 +-
 .../maven/impl/DefaultToolchainManagerTest.java    | 122 ++++++++++
 .../apache/maven/impl/standalone/ApiRunner.java    |   9 +
 .../maven-it-plugin-toolchain/pom.xml              |   2 +-
 its/core-it-support/core-it-toolchain/pom.xml      |  22 +-
 .../coreit/toolchain/CoreItToolchainFactory.java   |   6 +-
 .../main/resources/META-INF/plexus/components.xml  |  29 ---
 42 files changed, 865 insertions(+), 712 deletions(-)

diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java 
b/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java
index d9899dcc4c..e5764615b4 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java
@@ -34,6 +34,7 @@
 import org.apache.maven.api.services.DependencyCoordinatesFactory;
 import org.apache.maven.api.services.VersionResolverException;
 import org.apache.maven.api.settings.Settings;
+import org.apache.maven.api.toolchain.ToolchainModel;
 
 /**
  * The session to install / deploy / resolve artifacts and dependencies.
@@ -60,6 +61,14 @@ public interface Session extends ProtoSession {
     @Nonnull
     Settings getSettings();
 
+    /**
+     * Retrieves toolchain models that have been explicitly configured.
+     *
+     * @return the toolchain models
+     */
+    @Nonnull
+    Collection<ToolchainModel> getToolchains();
+
     /**
      * Retrieves the local repository associated with this session.
      *
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/Toolchain.java 
b/api/maven-api-core/src/main/java/org/apache/maven/api/Toolchain.java
index dcd17b41c6..dcbe72ea4a 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/Toolchain.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Toolchain.java
@@ -21,6 +21,7 @@
 import java.util.Map;
 
 import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.toolchain.ToolchainModel;
 
 /**
  * Represents a toolchain in the Maven build system.
@@ -70,6 +71,13 @@ public interface Toolchain {
      */
     String getType();
 
+    /**
+     * Gets the underlying toolchain model.
+     *
+     * @return the toolchain model
+     */
+    ToolchainModel getModel();
+
     /**
      * Gets the platform tool executable.
      *
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainFactory.java
 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainFactory.java
index 1a9baa33e7..d564026575 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainFactory.java
+++ 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainFactory.java
@@ -18,14 +18,41 @@
  */
 package org.apache.maven.api.services;
 
+import java.util.Optional;
+
+import org.apache.maven.api.Toolchain;
 import org.apache.maven.api.annotations.Consumer;
 import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Nonnull;
+import org.apache.maven.api.toolchain.ToolchainModel;
 
 /**
+ * Factory interface for creating toolchain instances from configuration 
models.
+ *
+ * <p>This factory is responsible for instantiating concrete toolchain 
implementations
+ * based on toolchain model configurations or default settings.</p>
+ *
  * @since 4.0.0
  */
 @Experimental
 @Consumer
 public interface ToolchainFactory {
-    // TODO: implement ToolchainFactory
+    /**
+     * Creates a toolchain instance from the provided model configuration.
+     *
+     * @param model The toolchain configuration model
+     * @return A configured toolchain instance
+     * @throws ToolchainFactoryException if toolchain creation fails
+     */
+    @Nonnull
+    Toolchain createToolchain(@Nonnull ToolchainModel model) throws 
ToolchainFactoryException;
+
+    /**
+     * Creates a default toolchain instance using system defaults.
+     *
+     * @return Optional containing the default toolchain if available
+     * @throws ToolchainFactoryException if default toolchain creation fails
+     */
+    @Nonnull
+    Optional<Toolchain> createDefaultToolchain() throws 
ToolchainFactoryException;
 }
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/MisconfiguredToolchainException.java
 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainFactoryException.java
similarity index 63%
copy from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/MisconfiguredToolchainException.java
copy to 
api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainFactoryException.java
index 1cffaf9020..5af3e09859 100644
--- 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/MisconfiguredToolchainException.java
+++ 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainFactoryException.java
@@ -16,18 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.toolchain;
+package org.apache.maven.api.services;
 
 /**
+ * Exception thrown when toolchain factory operations fail.
  *
+ * <p>This exception wraps errors that occur during toolchain creation or 
initialization.</p>
  */
-public class MisconfiguredToolchainException extends Exception {
+public class ToolchainFactoryException extends MavenException {
 
-    public MisconfiguredToolchainException(String message) {
+    public ToolchainFactoryException(String message) {
         super(message);
     }
 
-    public MisconfiguredToolchainException(String message, Throwable orig) {
-        super(message, orig);
+    public ToolchainFactoryException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public ToolchainFactoryException(Throwable cause) {
+        super(cause);
     }
 }
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainManager.java
 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainManager.java
index e428f819a4..b867cd4f08 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainManager.java
+++ 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainManager.java
@@ -29,7 +29,12 @@
 import org.apache.maven.api.annotations.Nonnull;
 
 /**
- * Service to manage {@link Toolchain}s.
+ * Service interface for managing Maven toolchains, which provide abstraction 
for different
+ * build tools and environments.
+ *
+ * <p>A toolchain represents a specific build tool configuration (e.g., JDK, 
compiler) that can be
+ * used during the Maven build process. This service allows for retrieving, 
storing, and managing
+ * these toolchains.</p>
  *
  * @since 4.0.0
  */
@@ -37,42 +42,50 @@
 public interface ToolchainManager extends Service {
 
     /**
+     * Retrieves toolchains matching the specified type and requirements.
      *
-     * @param session
-     * @param type
-     * @param requirements
-     * @return the selected {@link Toolchain}s
-     * @throws ToolchainManagerException if an exception occurs
+     * @param session The Maven session context
+     * @param type The type of toolchain (e.g., "jdk", "compiler")
+     * @param requirements Key-value pairs specifying toolchain requirements 
(e.g., "version": "11")
+     * @return List of matching toolchains, never null
+     * @throws ToolchainManagerException if toolchain retrieval fails
      */
     @Nonnull
     List<Toolchain> getToolchains(@Nonnull Session session, String type, 
Map<String, String> requirements);
 
     /**
+     * Retrieves all toolchains of the specified type without additional 
requirements.
      *
-     * @param session
-     * @param type
-     * @return the selected {@link Toolchain}
-     * @throws ToolchainManagerException if an exception occurs
+     * @param session The Maven session context
+     * @param type The type of toolchain to retrieve
+     * @return List of matching toolchains, never null
+     * @throws ToolchainManagerException if toolchain retrieval fails
      */
     @Nonnull
-    Optional<Toolchain> getToolchainFromBuildContext(@Nonnull Session session, 
String type)
-            throws ToolchainManagerException;
+    default List<Toolchain> getToolchains(@Nonnull Session session, @Nonnull 
String type)
+            throws ToolchainManagerException {
+        return getToolchains(session, type, null);
+    }
 
     /**
+     * Retrieves the currently active toolchain from the build context.
      *
-     * @param session
-     * @param type
-     * @return the selected {@link Toolchain}s
-     * @throws ToolchainManagerException if an exception occurs
+     * @param session The Maven session context
+     * @param type The type of toolchain to retrieve
+     * @return Optional containing the toolchain if found
+     * @throws ToolchainManagerException if toolchain retrieval fails
      */
     @Nonnull
-    List<Toolchain> getToolchainsForType(@Nonnull Session session, String 
type) throws ToolchainManagerException;
+    Optional<Toolchain> getToolchainFromBuildContext(@Nonnull Session session, 
@Nonnull String type)
+            throws ToolchainManagerException;
 
     /**
+     * Stores a toolchain in the build context for later retrieval.
      *
-     * @param session
-     * @param toolchain
-     * @throws ToolchainManagerException if an exception occurs
+     * @param session The Maven session context
+     * @param toolchain The toolchain to store
+     * @throws ToolchainManagerException if storing the toolchain fails
      */
-    void storeToolchainToBuildContext(@Nonnull Session session, Toolchain 
toolchain) throws ToolchainManagerException;
+    void storeToolchainToBuildContext(@Nonnull Session session, @Nonnull 
Toolchain toolchain)
+            throws ToolchainManagerException;
 }
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchain.java
 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/DefaultToolchain.java
similarity index 100%
rename from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchain.java
rename to 
compat/maven-compat/src/main/java/org/apache/maven/toolchain/DefaultToolchain.java
diff --git 
a/compat/maven-compat/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java
 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java
new file mode 100644
index 0000000000..7f8ae326c0
--- /dev/null
+++ 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java
@@ -0,0 +1,181 @@
+/*
+ * 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.toolchain;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.apache.maven.api.annotations.Nonnull;
+import org.apache.maven.api.di.Inject;
+import org.apache.maven.api.di.Named;
+import org.apache.maven.api.di.Singleton;
+import org.apache.maven.api.services.Lookup;
+import org.apache.maven.api.services.ToolchainFactoryException;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.impl.MappedList;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.slf4j.Logger;
+
+@Named
+@Singleton
+public class DefaultToolchainManager implements ToolchainManager, 
ToolchainManagerPrivate {
+
+    private final Lookup lookup;
+    private final Logger logger;
+
+    @Inject
+    public DefaultToolchainManager(Lookup lookup) {
+        this(lookup, null);
+    }
+
+    protected DefaultToolchainManager(Lookup lookup, Logger logger) {
+        this.lookup = lookup;
+        this.logger = logger;
+    }
+
+    private org.apache.maven.impl.DefaultToolchainManager getDelegate() {
+        return getToolchainManager(lookup, logger);
+    }
+
+    private org.apache.maven.impl.DefaultToolchainManager 
getToolchainManager(Lookup lookup, Logger logger) {
+        return getToolchainManager(
+                lookup.lookupMap(ToolchainFactory.class),
+                
lookup.lookupMap(org.apache.maven.api.services.ToolchainFactory.class),
+                logger);
+    }
+
+    private org.apache.maven.impl.DefaultToolchainManager getToolchainManager(
+            Map<String, ToolchainFactory> v3Factories,
+            Map<String, org.apache.maven.api.services.ToolchainFactory> 
v4Factories,
+            Logger logger) {
+        Map<String, org.apache.maven.api.services.ToolchainFactory> 
allFactories = new HashMap<>();
+        for (Map.Entry<String, ToolchainFactory> entry : 
v3Factories.entrySet()) {
+            ToolchainFactory v3Factory = entry.getValue();
+            allFactories.put(entry.getKey(), new 
org.apache.maven.api.services.ToolchainFactory() {
+                @Nonnull
+                @Override
+                public org.apache.maven.api.Toolchain createToolchain(
+                        @Nonnull org.apache.maven.api.toolchain.ToolchainModel 
model) throws ToolchainFactoryException {
+                    try {
+                        return getToolchainV4(v3Factory.createToolchain(new 
ToolchainModel(model)));
+                    } catch (MisconfiguredToolchainException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+
+                @Nonnull
+                @Override
+                public Optional<org.apache.maven.api.Toolchain> 
createDefaultToolchain()
+                        throws ToolchainFactoryException {
+                    return 
Optional.ofNullable(v3Factory.createDefaultToolchain())
+                            .map(DefaultToolchainManager.this::getToolchainV4);
+                }
+            });
+        }
+        allFactories.putAll(v4Factories);
+        return new org.apache.maven.impl.DefaultToolchainManager(allFactories, 
logger) {};
+    }
+
+    @Override
+    public Toolchain getToolchainFromBuildContext(String type, MavenSession 
session) {
+        return getDelegate()
+                .getToolchainFromBuildContext(session.getSession(), type)
+                .map(this::getToolchainV3)
+                .orElse(null);
+    }
+
+    @Override
+    public List<Toolchain> getToolchains(MavenSession session, String type, 
Map<String, String> requirements) {
+        return new MappedList<>(
+                getDelegate().getToolchains(session.getSession(), type, 
requirements), this::getToolchainV3);
+    }
+
+    @Override
+    public ToolchainPrivate[] getToolchainsForType(String type, MavenSession 
session)
+            throws MisconfiguredToolchainException {
+        try {
+            List<org.apache.maven.api.Toolchain> toolchains = 
getDelegate().getToolchains(session.getSession(), type);
+            return 
toolchains.stream().map(this::getToolchainV3).toArray(ToolchainPrivate[]::new);
+        } catch (org.apache.maven.api.services.ToolchainManagerException e) {
+            throw new MisconfiguredToolchainException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public void storeToolchainToBuildContext(ToolchainPrivate toolchain, 
MavenSession session) {
+        org.apache.maven.api.Toolchain tc = getToolchainV4(toolchain);
+        getDelegate().storeToolchainToBuildContext(session.getSession(), tc);
+    }
+
+    private org.apache.maven.api.Toolchain getToolchainV4(ToolchainPrivate 
toolchain) {
+        return toolchain instanceof ToolchainWrapperV3 v3tc ? v3tc.delegate : 
new ToolchainWrapperV4(toolchain);
+    }
+
+    private ToolchainPrivate getToolchainV3(org.apache.maven.api.Toolchain 
toolchain) {
+        return toolchain instanceof ToolchainWrapperV4 v3tc ? v3tc.delegate : 
new ToolchainWrapperV3(toolchain);
+    }
+
+    private record ToolchainWrapperV4(ToolchainPrivate delegate) implements 
org.apache.maven.api.Toolchain {
+
+        @Override
+        public String getType() {
+            return delegate.getType();
+        }
+
+        @Override
+        public String findTool(String toolName) {
+            return delegate.findTool(toolName);
+        }
+
+        @Override
+        public org.apache.maven.api.toolchain.ToolchainModel getModel() {
+            return delegate.getModel().getDelegate();
+        }
+
+        @Override
+        public boolean matchesRequirements(Map<String, String> requirements) {
+            return delegate.matchesRequirements(requirements);
+        }
+    }
+
+    private record ToolchainWrapperV3(org.apache.maven.api.Toolchain delegate) 
implements Toolchain, ToolchainPrivate {
+
+        @Override
+        public String getType() {
+            return delegate.getType();
+        }
+
+        @Override
+        public String findTool(String toolName) {
+            return delegate.findTool(toolName);
+        }
+
+        @Override
+        public boolean matchesRequirements(Map<String, String> requirements) {
+            return delegate.matchesRequirements(requirements);
+        }
+
+        @Override
+        public ToolchainModel getModel() {
+            return new ToolchainModel(delegate.getModel());
+        }
+    }
+}
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/MisconfiguredToolchainException.java
 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/MisconfiguredToolchainException.java
similarity index 100%
rename from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/MisconfiguredToolchainException.java
rename to 
compat/maven-compat/src/main/java/org/apache/maven/toolchain/MisconfiguredToolchainException.java
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/RequirementMatcher.java
 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/RequirementMatcher.java
similarity index 100%
rename from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/RequirementMatcher.java
rename to 
compat/maven-compat/src/main/java/org/apache/maven/toolchain/RequirementMatcher.java
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/RequirementMatcherFactory.java
 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/RequirementMatcherFactory.java
similarity index 100%
rename from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/RequirementMatcherFactory.java
rename to 
compat/maven-compat/src/main/java/org/apache/maven/toolchain/RequirementMatcherFactory.java
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/Toolchain.java 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/Toolchain.java
similarity index 100%
rename from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/Toolchain.java
rename to 
compat/maven-compat/src/main/java/org/apache/maven/toolchain/Toolchain.java
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainFactory.java
 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/ToolchainFactory.java
similarity index 100%
rename from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainFactory.java
rename to 
compat/maven-compat/src/main/java/org/apache/maven/toolchain/ToolchainFactory.java
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManager.java
 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/ToolchainManager.java
similarity index 100%
rename from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManager.java
rename to 
compat/maven-compat/src/main/java/org/apache/maven/toolchain/ToolchainManager.java
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManagerPrivate.java
 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/ToolchainManagerPrivate.java
similarity index 100%
rename from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManagerPrivate.java
rename to 
compat/maven-compat/src/main/java/org/apache/maven/toolchain/ToolchainManagerPrivate.java
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainPrivate.java
 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/ToolchainPrivate.java
similarity index 100%
rename from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainPrivate.java
rename to 
compat/maven-compat/src/main/java/org/apache/maven/toolchain/ToolchainPrivate.java
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/java/DefaultJavaToolChain.java
 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/DefaultJavaToolChain.java
similarity index 100%
rename from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/java/DefaultJavaToolChain.java
rename to 
compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/DefaultJavaToolChain.java
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java
 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java
similarity index 100%
rename from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java
rename to 
compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java
 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java
similarity index 100%
rename from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java
rename to 
compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java
 
b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java
similarity index 100%
rename from 
impl/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java
rename to 
compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java
diff --git 
a/compat/maven-compat/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerTest.java
 
b/compat/maven-compat/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerTest.java
new file mode 100644
index 0000000000..cc5b514a33
--- /dev/null
+++ 
b/compat/maven-compat/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerTest.java
@@ -0,0 +1,264 @@
+/*
+ * 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.toolchain;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.apache.maven.api.Session;
+import org.apache.maven.api.services.Lookup;
+import org.apache.maven.api.services.ToolchainFactory;
+import org.apache.maven.api.toolchain.ToolchainModel;
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentMatchers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.slf4j.Logger;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyMap;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class DefaultToolchainManagerTest {
+    // Mocks to inject into toolchainManager
+    @Mock
+    private Logger logger;
+
+    private DefaultToolchainManager toolchainManager;
+
+    @Mock
+    private ToolchainFactory toolchainFactory_basicType;
+
+    @Mock
+    private ToolchainFactory toolchainFactory_rareType;
+
+    @Mock
+    private Lookup lookup;
+
+    @BeforeEach
+    void onSetup() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        Map<String, ToolchainFactory> factories = new HashMap<>();
+        factories.put("basic", toolchainFactory_basicType);
+        factories.put("rare", toolchainFactory_rareType);
+
+        when(lookup.lookupMap(ToolchainFactory.class)).thenReturn(factories);
+        
when(lookup.lookupMap(org.apache.maven.toolchain.ToolchainFactory.class))
+                .thenReturn(Map.of());
+
+        toolchainManager = new DefaultToolchainManager(lookup, logger);
+    }
+
+    @Test
+    void testNoModels() {
+        MavenSession session = mock(MavenSession.class);
+        MavenExecutionRequest executionRequest = new 
DefaultMavenExecutionRequest();
+        when(session.getRequest()).thenReturn(executionRequest);
+
+        List<Toolchain> toolchains = toolchainManager.getToolchains(session, 
"unknown", null);
+
+        assertEquals(0, toolchains.size());
+    }
+
+    @Test
+    void testModelNoFactory() {
+        MavenSession session = mock(MavenSession.class);
+        MavenExecutionRequest executionRequest = new 
DefaultMavenExecutionRequest();
+        List<ToolchainModel> toolchainModels = new ArrayList<>();
+        
toolchainModels.add(ToolchainModel.newBuilder().type("unknown").build());
+        when(session.getRequest()).thenReturn(executionRequest);
+        Session sessionv4 = mock(Session.class);
+        when(session.getSession()).thenReturn(sessionv4);
+        when(sessionv4.getToolchains()).thenReturn(toolchainModels);
+
+        List<Toolchain> toolchains = toolchainManager.getToolchains(session, 
"unknown", null);
+
+        assertEquals(0, toolchains.size());
+        verify(logger).error("Missing toolchain factory for type: unknown. 
Possibly caused by misconfigured project.");
+    }
+
+    @Test
+    void testModelAndFactory() {
+        MavenSession session = mock(MavenSession.class);
+        List<ToolchainModel> toolchainModels = List.of(
+                ToolchainModel.newBuilder().type("basic").build(),
+                ToolchainModel.newBuilder().type("basic").build(),
+                ToolchainModel.newBuilder().type("rare").build());
+        Session sessionv4 = mock(Session.class);
+        when(session.getSession()).thenReturn(sessionv4);
+        when(sessionv4.getToolchains()).thenReturn(toolchainModels);
+
+        org.apache.maven.api.Toolchain rareToolchain = 
mock(org.apache.maven.api.Toolchain.class);
+        
when(toolchainFactory_rareType.createToolchain(any())).thenReturn(rareToolchain);
+
+        List<Toolchain> toolchains = toolchainManager.getToolchains(session, 
"rare", null);
+
+        assertEquals(1, toolchains.size());
+    }
+
+    @Test
+    void testModelsAndFactory() {
+        MavenSession session = mock(MavenSession.class);
+        Session sessionv4 = mock(Session.class);
+        when(session.getSession()).thenReturn(sessionv4);
+        when(sessionv4.getToolchains())
+                .thenReturn(List.of(
+                        ToolchainModel.newBuilder().type("basic").build(),
+                        ToolchainModel.newBuilder().type("basic").build(),
+                        ToolchainModel.newBuilder().type("rare").build()));
+
+        org.apache.maven.api.Toolchain basicToolchain = 
mock(org.apache.maven.api.Toolchain.class);
+        
when(toolchainFactory_basicType.createToolchain(any())).thenReturn(basicToolchain);
+        org.apache.maven.api.Toolchain basicToolchain2 = 
mock(org.apache.maven.api.Toolchain.class);
+        
when(toolchainFactory_basicType.createToolchain(any())).thenReturn(basicToolchain2);
+
+        List<Toolchain> toolchains = toolchainManager.getToolchains(session, 
"basic", null);
+
+        assertEquals(2, toolchains.size());
+    }
+
+    @Test
+    void testRequirements() throws Exception {
+        MavenSession session = mock(MavenSession.class);
+        MavenExecutionRequest executionRequest = new 
DefaultMavenExecutionRequest();
+        when(session.getRequest()).thenReturn(executionRequest);
+        Session sessionv4 = mock(Session.class);
+        when(session.getSession()).thenReturn(sessionv4);
+        when(sessionv4.getToolchains())
+                .thenReturn(List.of(
+                        ToolchainModel.newBuilder().type("basic").build(),
+                        ToolchainModel.newBuilder().type("rare").build()));
+
+        org.apache.maven.api.Toolchain basicPrivate = 
mock(org.apache.maven.api.Toolchain.class);
+        when(basicPrivate.matchesRequirements(anyMap())).thenReturn(false);
+        
when(basicPrivate.matchesRequirements(ArgumentMatchers.eq(Map.of("key", 
"value"))))
+                .thenReturn(true);
+        
when(toolchainFactory_basicType.createToolchain(isA(org.apache.maven.api.toolchain.ToolchainModel.class)))
+                .thenReturn(basicPrivate);
+
+        List<Toolchain> toolchains =
+                toolchainManager.getToolchains(session, "basic", 
Collections.singletonMap("key", "value"));
+
+        assertEquals(1, toolchains.size());
+    }
+
+    @Test
+    void testToolchainsForAvailableType() throws Exception {
+        // prepare
+        MavenSession session = mock(MavenSession.class);
+        MavenExecutionRequest req = new DefaultMavenExecutionRequest();
+        when(session.getRequest()).thenReturn(req);
+        Session sessionv4 = mock(Session.class);
+        when(session.getSession()).thenReturn(sessionv4);
+
+        org.apache.maven.api.Toolchain basicToolchain = 
mock(org.apache.maven.api.Toolchain.class);
+        
when(toolchainFactory_basicType.createDefaultToolchain()).thenReturn(Optional.of(basicToolchain));
+        org.apache.maven.api.Toolchain rareToolchain = 
mock(org.apache.maven.api.Toolchain.class);
+        
when(toolchainFactory_rareType.createDefaultToolchain()).thenReturn(Optional.of(rareToolchain));
+
+        // execute
+        ToolchainPrivate[] toolchains = 
toolchainManager.getToolchainsForType("basic", session);
+
+        // verify
+        verify(logger, never()).error(anyString());
+        assertEquals(1, toolchains.length);
+    }
+
+    @Test
+    void testToolchainsForUnknownType() throws Exception {
+        // prepare
+        MavenSession session = mock(MavenSession.class);
+        MavenExecutionRequest req = new DefaultMavenExecutionRequest();
+        when(session.getRequest()).thenReturn(req);
+
+        org.apache.maven.api.Toolchain basicToolchain = 
mock(org.apache.maven.api.Toolchain.class);
+        
when(toolchainFactory_basicType.createDefaultToolchain()).thenReturn(Optional.of(basicToolchain));
+        org.apache.maven.api.Toolchain rareToolchain = 
mock(org.apache.maven.api.Toolchain.class);
+        
when(toolchainFactory_rareType.createDefaultToolchain()).thenReturn(Optional.of(rareToolchain));
+
+        // execute
+        ToolchainPrivate[] toolchains = 
toolchainManager.getToolchainsForType("unknown", session);
+
+        // verify
+        verify(logger).error("Missing toolchain factory for type: unknown. 
Possibly caused by misconfigured project.");
+        assertEquals(0, toolchains.length);
+    }
+
+    @Test
+    void testToolchainsForConfiguredType() throws Exception {
+        // prepare
+        MavenSession session = mock(MavenSession.class);
+        MavenExecutionRequest req = new DefaultMavenExecutionRequest();
+        when(session.getRequest()).thenReturn(req);
+        Session sessionv4 = mock(Session.class);
+        when(session.getSession()).thenReturn(sessionv4);
+        List<ToolchainModel> toolchainModels = new ArrayList<>();
+        when(sessionv4.getToolchains()).thenReturn(toolchainModels);
+
+        ToolchainModel basicToolchainModel =
+                ToolchainModel.newBuilder().type("basic").build();
+        toolchainModels.add(basicToolchainModel);
+        toolchainModels.add(basicToolchainModel);
+
+        ToolchainModel rareToolchainModel =
+                ToolchainModel.newBuilder().type("rare").build();
+        toolchainModels.add(rareToolchainModel);
+
+        org.apache.maven.api.Toolchain basic = 
mock(org.apache.maven.api.Toolchain.class);
+        
when(toolchainFactory_basicType.createToolchain(basicToolchainModel)).thenReturn(basic);
+
+        // execute
+        ToolchainPrivate[] toolchains = 
toolchainManager.getToolchainsForType("basic", session);
+
+        // verify
+        verify(logger, never()).error(anyString());
+        assertEquals(2, toolchains.length);
+    }
+
+    @Test
+    void testMisconfiguredToolchain() throws Exception {
+        // prepare
+        MavenSession session = mock(MavenSession.class);
+        MavenExecutionRequest req = new DefaultMavenExecutionRequest();
+        when(session.getRequest()).thenReturn(req);
+        Session sessionv4 = mock(Session.class);
+        when(session.getSession()).thenReturn(sessionv4);
+
+        // execute
+        ToolchainPrivate[] basics = 
toolchainManager.getToolchainsForType("basic", session);
+
+        // verify
+        assertEquals(0, basics.length);
+    }
+}
diff --git 
a/impl/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainTest.java
 
b/compat/maven-compat/src/test/java/org/apache/maven/toolchain/DefaultToolchainTest.java
similarity index 100%
rename from 
impl/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainTest.java
rename to 
compat/maven-compat/src/test/java/org/apache/maven/toolchain/DefaultToolchainTest.java
diff --git 
a/impl/maven-core/src/test/java/org/apache/maven/toolchain/RequirementMatcherFactoryTest.java
 
b/compat/maven-compat/src/test/java/org/apache/maven/toolchain/RequirementMatcherFactoryTest.java
similarity index 100%
rename from 
impl/maven-core/src/test/java/org/apache/maven/toolchain/RequirementMatcherFactoryTest.java
rename to 
compat/maven-compat/src/test/java/org/apache/maven/toolchain/RequirementMatcherFactoryTest.java
diff --git a/impl/maven-cli/pom.xml b/impl/maven-cli/pom.xml
index e8653c74c6..668227bb9a 100644
--- a/impl/maven-cli/pom.xml
+++ b/impl/maven-cli/pom.xml
@@ -188,6 +188,11 @@ under the License.
       <optional>true</optional>
     </dependency>
 
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-compat</artifactId>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter-api</artifactId>
diff --git 
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupContext.java
 
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupContext.java
index a4045cd8f7..d468c54041 100644
--- 
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupContext.java
+++ 
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupContext.java
@@ -34,6 +34,7 @@
 import org.apache.maven.api.cli.Logger;
 import org.apache.maven.api.services.Lookup;
 import org.apache.maven.api.settings.Settings;
+import org.apache.maven.api.toolchain.PersistedToolchains;
 import org.apache.maven.cling.logging.Slf4jConfiguration;
 import org.apache.maven.eventspy.internal.EventSpyDispatcher;
 import org.apache.maven.logging.BuildEventListener;
@@ -106,6 +107,7 @@ public LookupContext(InvokerRequest invokerRequest, boolean 
containerCapsuleMana
     public boolean interactive;
     public Path localRepositoryPath;
     public Settings effectiveSettings;
+    public PersistedToolchains effectiveToolchains;
 
     public final List<AutoCloseable> closeables = new ArrayList<>();
 
diff --git 
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java
 
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java
index e63ea2f12f..393c31b782 100644
--- 
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java
+++ 
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java
@@ -25,9 +25,11 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.function.Consumer;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import org.apache.maven.InternalErrorException;
 import org.apache.maven.Maven;
@@ -44,6 +46,7 @@
 import org.apache.maven.api.services.ToolchainsBuilderRequest;
 import org.apache.maven.api.services.ToolchainsBuilderResult;
 import org.apache.maven.api.services.model.ModelProcessor;
+import org.apache.maven.api.toolchain.PersistedToolchains;
 import org.apache.maven.cling.event.ExecutionEventLogger;
 import org.apache.maven.cling.invoker.LookupContext;
 import org.apache.maven.cling.invoker.LookupInvoker;
@@ -58,7 +61,6 @@
 import org.apache.maven.execution.DefaultMavenExecutionRequest;
 import org.apache.maven.execution.ExecutionListener;
 import org.apache.maven.execution.MavenExecutionRequest;
-import org.apache.maven.execution.MavenExecutionRequestPopulator;
 import org.apache.maven.execution.MavenExecutionResult;
 import org.apache.maven.execution.ProfileActivation;
 import org.apache.maven.execution.ProjectActivation;
@@ -67,6 +69,7 @@
 import org.apache.maven.logging.LoggingExecutionListener;
 import org.apache.maven.logging.MavenTransferListener;
 import org.apache.maven.project.MavenProject;
+import org.apache.maven.toolchain.model.ToolchainModel;
 import org.eclipse.aether.DefaultRepositoryCache;
 import org.eclipse.aether.transfer.TransferListener;
 
@@ -197,12 +200,7 @@ protected void toolchains(MavenContext context, 
MavenExecutionRequest request) t
 
         context.eventSpyDispatcher.onEvent(toolchainsResult);
 
-        context.lookup
-                .lookup(MavenExecutionRequestPopulator.class)
-                .populateFromToolchains(
-                        request,
-                        new 
org.apache.maven.toolchain.model.PersistedToolchains(
-                                toolchainsResult.getEffectiveToolchains()));
+        context.effectiveToolchains = 
toolchainsResult.getEffectiveToolchains();
 
         if (toolchainsResult.getProblems().hasWarningProblems()) {
             int totalProblems = 
toolchainsResult.getProblems().totalProblemsReported();
@@ -233,6 +231,12 @@ protected void populateRequest(MavenContext context, 
Lookup lookup, MavenExecuti
             request.setRootDirectory(context.invokerRequest.topDirectory());
         }
 
+        request.setToolchains(
+                
Optional.ofNullable(context.effectiveToolchains).map(PersistedToolchains::getToolchains).stream()
+                        .flatMap(List::stream)
+                        .map(ToolchainModel::new)
+                        
.collect(Collectors.groupingBy(ToolchainModel::getType)));
+
         MavenOptions options = (MavenOptions) context.invokerRequest.options();
         
request.setNoSnapshotUpdates(options.suppressSnapshotUpdates().orElse(false));
         request.setGoals(options.goals().orElse(List.of()));
diff --git a/impl/maven-core/pom.xml b/impl/maven-core/pom.xml
index 18b2795703..966ecda1cd 100644
--- a/impl/maven-core/pom.xml
+++ b/impl/maven-core/pom.xml
@@ -348,8 +348,6 @@ under the License.
               
<exclude>org.apache.maven.project.DefaultProjectDependenciesResolver#DefaultProjectDependenciesResolver()</exclude>
               
<exclude>org.apache.maven.rtinfo.internal.DefaultRuntimeInformation#DefaultRuntimeInformation()</exclude>
               
<exclude>org.apache.maven.settings.DefaultMavenSettingsBuilder#DefaultMavenSettingsBuilder()</exclude>
-              
<exclude>org.apache.maven.toolchain.DefaultToolchainManager#DefaultToolchainManager():CONSTRUCTOR_REMOVED</exclude>
-              
<exclude>org.apache.maven.toolchain.DefaultToolchainManagerPrivate#DefaultToolchainManagerPrivate()</exclude>
               <!-- END default constructor on Plexus/JSR 330 components -->
               <!-- system property with that name no longer evaluated -->
               
<exclude>org.apache.maven.project.DefaultProjectBuilder#DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY</exclude>
@@ -384,7 +382,18 @@ under the License.
               <exclude>org.apache.maven.repository.RepositorySystem</exclude>
               
<exclude>org.apache.maven.settings.DefaultMavenSettingsBuilder</exclude>
               <exclude>org.apache.maven.settings.MavenSettingsBuilder</exclude>
+              <exclude>org.apache.maven.toolchain.DefaultToolchain</exclude>
               
<exclude>org.apache.maven.toolchain.DefaultToolchainsBuilder</exclude>
+              
<exclude>org.apache.maven.toolchain.DefaultToolchainManager</exclude>
+              
<exclude>org.apache.maven.toolchain.DefaultToolchainManagerPrivate</exclude>
+              
<exclude>org.apache.maven.toolchain.MisconfiguredToolchainException</exclude>
+              <exclude>org.apache.maven.toolchain.RequirementMatcher</exclude>
+              
<exclude>org.apache.maven.toolchain.RequirementMatcherFactory</exclude>
+              <exclude>org.apache.maven.toolchain.Toolchain</exclude>
+              <exclude>org.apache.maven.toolchain.ToolchainFactory</exclude>
+              <exclude>org.apache.maven.toolchain.ToolchainManager</exclude>
+              
<exclude>org.apache.maven.toolchain.ToolchainManagerPrivate</exclude>
+              <exclude>org.apache.maven.toolchain.ToolchainPrivate</exclude>
               <exclude>org.apache.maven.toolchain.ToolchainsBuilder</exclude>
             </excludes>
           </parameter>
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java
 
b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java
index d105759853..0341d9dc6c 100644
--- 
a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java
+++ 
b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java
@@ -20,6 +20,7 @@
 
 import java.nio.file.Path;
 import java.time.Instant;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -37,6 +38,7 @@
 import org.apache.maven.api.services.LookupException;
 import org.apache.maven.api.services.MavenException;
 import org.apache.maven.api.settings.Settings;
+import org.apache.maven.api.toolchain.ToolchainModel;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.bridge.MavenRepositorySystem;
 import org.apache.maven.execution.MavenSession;
@@ -112,6 +114,15 @@ public Settings getSettings() {
         return getMavenSession().getSettings().getDelegate();
     }
 
+    @Nonnull
+    @Override
+    public Collection<ToolchainModel> getToolchains() {
+        return getMavenSession().getRequest().getToolchains().values().stream()
+                .flatMap(Collection::stream)
+                
.map(org.apache.maven.toolchain.model.ToolchainModel::getDelegate)
+                .toList();
+    }
+
     @Nonnull
     @Override
     public Map<String, String> getUserProperties() {
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultToolchainManager.java
 
b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultToolchainManager.java
deleted file mode 100644
index 3370ba5175..0000000000
--- 
a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultToolchainManager.java
+++ /dev/null
@@ -1,117 +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.internal.impl;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-import org.apache.maven.api.Session;
-import org.apache.maven.api.Toolchain;
-import org.apache.maven.api.services.ToolchainManager;
-import org.apache.maven.api.services.ToolchainManagerException;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.impl.MappedList;
-import org.apache.maven.toolchain.DefaultToolchainManagerPrivate;
-import org.apache.maven.toolchain.MisconfiguredToolchainException;
-import org.apache.maven.toolchain.ToolchainPrivate;
-
-@Named
-@Singleton
-public class DefaultToolchainManager implements ToolchainManager {
-    private final DefaultToolchainManagerPrivate toolchainManagerPrivate;
-
-    @Inject
-    public DefaultToolchainManager(DefaultToolchainManagerPrivate 
toolchainManagerPrivate) {
-        this.toolchainManagerPrivate = toolchainManagerPrivate;
-    }
-
-    @Override
-    public List<Toolchain> getToolchains(Session session, String type, 
Map<String, String> requirements)
-            throws ToolchainManagerException {
-        MavenSession s = InternalMavenSession.from(session).getMavenSession();
-        List<org.apache.maven.toolchain.Toolchain> toolchains =
-                toolchainManagerPrivate.getToolchains(s, type, requirements);
-        return new MappedList<>(toolchains, this::toToolchain);
-    }
-
-    @Override
-    public Optional<Toolchain> getToolchainFromBuildContext(Session session, 
String type)
-            throws ToolchainManagerException {
-        MavenSession s = InternalMavenSession.from(session).getMavenSession();
-        return 
Optional.ofNullable(toolchainManagerPrivate.getToolchainFromBuildContext(type, 
s))
-                .map(this::toToolchain);
-    }
-
-    @Override
-    public List<Toolchain> getToolchainsForType(Session session, String type) 
throws ToolchainManagerException {
-        try {
-            MavenSession s = 
InternalMavenSession.from(session).getMavenSession();
-            ToolchainPrivate[] toolchains = 
toolchainManagerPrivate.getToolchainsForType(type, s);
-            return new MappedList<>(Arrays.asList(toolchains), 
this::toToolchain);
-        } catch (MisconfiguredToolchainException e) {
-            throw new ToolchainManagerException("Unable to get toochains for 
type " + type, e);
-        }
-    }
-
-    @Override
-    public void storeToolchainToBuildContext(Session session, Toolchain 
toolchain) throws ToolchainManagerException {
-        MavenSession s = InternalMavenSession.from(session).getMavenSession();
-        org.apache.maven.toolchain.ToolchainPrivate tc =
-                (org.apache.maven.toolchain.ToolchainPrivate) 
((ToolchainWrapper) toolchain).toolchain;
-        toolchainManagerPrivate.storeToolchainToBuildContext(tc, s);
-    }
-
-    private Toolchain toToolchain(org.apache.maven.toolchain.Toolchain 
toolchain) {
-        return new ToolchainWrapper(toolchain);
-    }
-
-    private static class ToolchainWrapper implements Toolchain {
-        private final org.apache.maven.toolchain.Toolchain toolchain;
-
-        ToolchainWrapper(org.apache.maven.toolchain.Toolchain toolchain) {
-            this.toolchain = toolchain;
-        }
-
-        @Override
-        public String getType() {
-            return toolchain.getType();
-        }
-
-        @Override
-        public String findTool(String toolName) {
-            return toolchain.findTool(toolName);
-        }
-
-        @Override
-        public boolean matchesRequirements(Map<String, String> requirements) {
-            return ((ToolchainPrivate) 
toolchain).matchesRequirements(requirements);
-        }
-
-        @Override
-        public String toString() {
-            return toolchain.toString();
-        }
-    }
-}
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java
 
b/impl/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java
deleted file mode 100644
index 4cdc6f3ef9..0000000000
--- 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java
+++ /dev/null
@@ -1,135 +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.toolchain;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.plugin.descriptor.PluginDescriptor;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.toolchain.model.ToolchainModel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- */
-@Named
-@Singleton
-public class DefaultToolchainManager implements ToolchainManager {
-    protected final Logger logger; // TODO this class is extended, needs 
refactoring
-
-    final Map<String, ToolchainFactory> factories;
-
-    @Inject
-    public DefaultToolchainManager(Map<String, ToolchainFactory> factories) {
-        this.factories = factories;
-        this.logger = LoggerFactory.getLogger(DefaultToolchainManager.class);
-    }
-
-    /**
-     * Ctor needed for UT.
-     */
-    DefaultToolchainManager(Map<String, ToolchainFactory> factories, Logger 
logger) {
-        this.factories = factories;
-        this.logger = requireNonNull(logger);
-    }
-
-    @Override
-    public Toolchain getToolchainFromBuildContext(String type, MavenSession 
session) {
-        Map<String, Object> context = retrieveContext(session);
-
-        ToolchainModel model = (ToolchainModel) 
context.get(getStorageKey(type));
-
-        if (model != null) {
-            List<Toolchain> toolchains = 
selectToolchains(Collections.singletonList(model), type, null);
-
-            if (!toolchains.isEmpty()) {
-                return toolchains.get(0);
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public List<Toolchain> getToolchains(MavenSession session, String type, 
Map<String, String> requirements) {
-        List<ToolchainModel> models = 
session.getRequest().getToolchains().get(type);
-
-        return selectToolchains(models, type, requirements);
-    }
-
-    private List<Toolchain> selectToolchains(
-            List<ToolchainModel> models, String type, Map<String, String> 
requirements) {
-        List<Toolchain> toolchains = new ArrayList<>();
-
-        if (models != null) {
-            ToolchainFactory fact = factories.get(type);
-
-            if (fact == null) {
-                logger.error(
-                        "Missing toolchain factory for type: " + type + ". 
Possibly caused by misconfigured project.");
-            } else {
-                for (ToolchainModel model : models) {
-                    try {
-                        ToolchainPrivate toolchain = 
fact.createToolchain(model);
-                        if (requirements == null || 
toolchain.matchesRequirements(requirements)) {
-                            toolchains.add(toolchain);
-                        }
-                    } catch (MisconfiguredToolchainException ex) {
-                        logger.error("Misconfigured toolchain.", ex);
-                    }
-                }
-            }
-        }
-        return toolchains;
-    }
-
-    Map<String, Object> retrieveContext(MavenSession session) {
-        Map<String, Object> context = null;
-
-        if (session != null) {
-            PluginDescriptor desc = new PluginDescriptor();
-            desc.setGroupId(PluginDescriptor.getDefaultPluginGroupId());
-            
desc.setArtifactId(PluginDescriptor.getDefaultPluginArtifactId("toolchains"));
-
-            MavenProject current = session.getCurrentProject();
-
-            if (current != null) {
-                // TODO why is this using the context
-                context = session.getPluginContext(desc, current);
-            }
-        }
-
-        return (context != null) ? context : new HashMap<>();
-    }
-
-    public static final String getStorageKey(String type) {
-        return "toolchain-" + type; // NOI18N
-    }
-}
diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java
 
b/impl/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java
deleted file mode 100644
index c5e8cf62c8..0000000000
--- 
a/impl/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java
+++ /dev/null
@@ -1,88 +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.toolchain;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.maven.api.toolchain.ToolchainModel;
-import org.apache.maven.execution.MavenSession;
-import org.slf4j.Logger;
-
-/**
- * TODO: refactor this, component extending component is bad practice.
- *
- */
-@Named
-@Singleton
-public class DefaultToolchainManagerPrivate extends DefaultToolchainManager 
implements ToolchainManagerPrivate {
-    @Inject
-    public DefaultToolchainManagerPrivate(Map<String, ToolchainFactory> 
factories) {
-        super(factories);
-    }
-
-    /**
-     * Ctor needed for UT.
-     */
-    DefaultToolchainManagerPrivate(Map<String, ToolchainFactory> factories, 
Logger logger) {
-        super(factories, logger);
-    }
-
-    @Override
-    public ToolchainPrivate[] getToolchainsForType(String type, MavenSession 
session)
-            throws MisconfiguredToolchainException {
-        List<ToolchainPrivate> toRet = new ArrayList<>();
-
-        ToolchainFactory fact = factories.get(type);
-        if (fact == null) {
-            logger.error("Missing toolchain factory for type: " + type + ". 
Possibly caused by misconfigured project.");
-        } else {
-            List<ToolchainModel> availableToolchains =
-                    
org.apache.maven.toolchain.model.ToolchainModel.toolchainModelToApiV4(
-                            session.getRequest().getToolchains().get(type));
-
-            if (availableToolchains != null) {
-                for (ToolchainModel toolchainModel : availableToolchains) {
-                    org.apache.maven.toolchain.model.ToolchainModel tm =
-                            new 
org.apache.maven.toolchain.model.ToolchainModel(toolchainModel);
-                    toRet.add(fact.createToolchain(tm));
-                }
-            }
-
-            // add default toolchain
-            ToolchainPrivate tool = fact.createDefaultToolchain();
-            if (tool != null) {
-                toRet.add(tool);
-            }
-        }
-
-        return toRet.toArray(new ToolchainPrivate[0]);
-    }
-
-    @Override
-    public void storeToolchainToBuildContext(ToolchainPrivate toolchain, 
MavenSession session) {
-        Map<String, Object> context = retrieveContext(session);
-        context.put(getStorageKey(toolchain.getType()), toolchain.getModel());
-    }
-}
diff --git 
a/impl/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java 
b/impl/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java
index 70863c4be6..7bb328744c 100644
--- a/impl/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java
+++ b/impl/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java
@@ -47,18 +47,18 @@
 import org.apache.maven.api.services.ProjectBuilder;
 import org.apache.maven.api.services.ProjectBuilderRequest;
 import org.apache.maven.api.services.SettingsBuilder;
+import org.apache.maven.api.services.ToolchainsBuilder;
 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
 import org.apache.maven.bridge.MavenRepositorySystem;
 import org.apache.maven.execution.DefaultMavenExecutionRequest;
 import org.apache.maven.execution.DefaultMavenExecutionResult;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.execution.scope.internal.MojoExecutionScope;
+import org.apache.maven.impl.DefaultToolchainManager;
 import org.apache.maven.impl.InternalSession;
 import org.apache.maven.impl.resolver.MavenSessionBuilderSupplier;
 import org.apache.maven.rtinfo.RuntimeInformation;
 import org.apache.maven.session.scope.internal.SessionScope;
-import org.apache.maven.toolchain.DefaultToolchainManagerPrivate;
-import org.apache.maven.toolchain.building.ToolchainsBuilder;
 import org.codehaus.plexus.PlexusContainer;
 import 
org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 import org.codehaus.plexus.testing.PlexusTest;
@@ -89,7 +89,7 @@ class TestApi {
     MavenRepositorySystem mavenRepositorySystem;
 
     @Inject
-    DefaultToolchainManagerPrivate toolchainManagerPrivate;
+    DefaultToolchainManager toolchainManagerPrivate;
 
     @Inject
     PlexusContainer plexusContainer;
diff --git 
a/impl/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivateTest.java
 
b/impl/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivateTest.java
deleted file mode 100644
index 4c255a37a4..0000000000
--- 
a/impl/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivateTest.java
+++ /dev/null
@@ -1,152 +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.toolchain;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.maven.execution.DefaultMavenExecutionRequest;
-import org.apache.maven.execution.MavenExecutionRequest;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.toolchain.model.ToolchainModel;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.slf4j.Logger;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-class DefaultToolchainManagerPrivateTest {
-    // Mocks to inject into toolchainManager
-    @Mock
-    private Logger logger;
-
-    @InjectMocks
-    private DefaultToolchainManagerPrivate toolchainManager;
-
-    @Mock
-    private ToolchainFactory toolchainFactory_basicType;
-
-    @Mock
-    private ToolchainFactory toolchainFactory_rareType;
-
-    @BeforeEach
-    void setUp() {
-
-        MockitoAnnotations.initMocks(this);
-
-        Map<String, ToolchainFactory> factories = new HashMap<>();
-        factories.put("basic", toolchainFactory_basicType);
-        factories.put("rare", toolchainFactory_rareType);
-        toolchainManager = new DefaultToolchainManagerPrivate(factories, 
logger);
-    }
-
-    @Test
-    void testToolchainsForAvailableType() throws Exception {
-        // prepare
-        MavenSession session = mock(MavenSession.class);
-        MavenExecutionRequest req = new DefaultMavenExecutionRequest();
-        when(session.getRequest()).thenReturn(req);
-
-        ToolchainPrivate basicToolchain = mock(ToolchainPrivate.class);
-        
when(toolchainFactory_basicType.createDefaultToolchain()).thenReturn(basicToolchain);
-        ToolchainPrivate rareToolchain = mock(ToolchainPrivate.class);
-        
when(toolchainFactory_rareType.createDefaultToolchain()).thenReturn(rareToolchain);
-
-        // execute
-        ToolchainPrivate[] toolchains = 
toolchainManager.getToolchainsForType("basic", session);
-
-        // verify
-        verify(logger, never()).error(anyString());
-        assertEquals(1, toolchains.length);
-    }
-
-    @Test
-    void testToolchainsForUnknownType() throws Exception {
-        // prepare
-        MavenSession session = mock(MavenSession.class);
-        MavenExecutionRequest req = new DefaultMavenExecutionRequest();
-        when(session.getRequest()).thenReturn(req);
-
-        ToolchainPrivate basicToolchain = mock(ToolchainPrivate.class);
-        
when(toolchainFactory_basicType.createDefaultToolchain()).thenReturn(basicToolchain);
-        ToolchainPrivate rareToolchain = mock(ToolchainPrivate.class);
-        
when(toolchainFactory_rareType.createDefaultToolchain()).thenReturn(rareToolchain);
-
-        // execute
-        ToolchainPrivate[] toolchains = 
toolchainManager.getToolchainsForType("unknown", session);
-
-        // verify
-        verify(logger).error("Missing toolchain factory for type: unknown. 
Possibly caused by misconfigured project.");
-        assertEquals(0, toolchains.length);
-    }
-
-    @Test
-    void testToolchainsForConfiguredType() throws Exception {
-        // prepare
-        MavenSession session = mock(MavenSession.class);
-        MavenExecutionRequest req = new DefaultMavenExecutionRequest();
-        when(session.getRequest()).thenReturn(req);
-        Map<String, List<ToolchainModel>> groupedToolchains = new HashMap<>();
-        req.setToolchains(groupedToolchains);
-
-        List<ToolchainModel> basicToolchains = new ArrayList<>();
-        ToolchainModel basicToolchainModel = new ToolchainModel();
-        basicToolchainModel.setType("basic");
-        basicToolchains.add(basicToolchainModel);
-        basicToolchains.add(basicToolchainModel);
-        groupedToolchains.put("basic", basicToolchains);
-
-        List<ToolchainModel> rareToolchains = new ArrayList<>();
-        ToolchainModel rareToolchainModel = new ToolchainModel();
-        rareToolchainModel.setType("rare");
-        rareToolchains.add(rareToolchainModel);
-        groupedToolchains.put("rare", rareToolchains);
-
-        // execute
-        ToolchainPrivate[] toolchains = 
toolchainManager.getToolchainsForType("basic", session);
-
-        // verify
-        verify(logger, never()).error(anyString());
-        assertEquals(2, toolchains.length);
-    }
-
-    @Test
-    void testMisconfiguredToolchain() throws Exception {
-        // prepare
-        MavenSession session = mock(MavenSession.class);
-        MavenExecutionRequest req = new DefaultMavenExecutionRequest();
-        when(session.getRequest()).thenReturn(req);
-
-        // execute
-        ToolchainPrivate[] basics = 
toolchainManager.getToolchainsForType("basic", session);
-
-        // verify
-        assertEquals(0, basics.length);
-    }
-}
diff --git 
a/impl/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerTest.java
 
b/impl/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerTest.java
deleted file mode 100644
index 485a7378fd..0000000000
--- 
a/impl/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerTest.java
+++ /dev/null
@@ -1,146 +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.toolchain;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.maven.execution.DefaultMavenExecutionRequest;
-import org.apache.maven.execution.MavenExecutionRequest;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.toolchain.model.ToolchainModel;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentMatchers;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.slf4j.Logger;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.isA;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-class DefaultToolchainManagerTest {
-    // Mocks to inject into toolchainManager
-    @Mock
-    private Logger logger;
-
-    @InjectMocks
-    private DefaultToolchainManager toolchainManager;
-
-    @Mock
-    private ToolchainFactory toolchainFactory_basicType;
-
-    @Mock
-    private ToolchainFactory toolchainFactory_rareType;
-
-    @BeforeEach
-    void onSetup() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        Map<String, ToolchainFactory> factories = new HashMap<>();
-        factories.put("basic", toolchainFactory_basicType);
-        factories.put("rare", toolchainFactory_rareType);
-        toolchainManager = new DefaultToolchainManager(factories, logger);
-    }
-
-    @Test
-    void testNoModels() {
-        MavenSession session = mock(MavenSession.class);
-        MavenExecutionRequest executionRequest = new 
DefaultMavenExecutionRequest();
-        when(session.getRequest()).thenReturn(executionRequest);
-
-        List<Toolchain> toolchains = toolchainManager.getToolchains(session, 
"unknown", null);
-
-        assertEquals(0, toolchains.size());
-    }
-
-    @Test
-    void testModelNoFactory() {
-        MavenSession session = mock(MavenSession.class);
-        MavenExecutionRequest executionRequest = new 
DefaultMavenExecutionRequest();
-        Map<String, List<ToolchainModel>> toolchainModels = new HashMap<>();
-        toolchainModels.put("unknown", Collections.singletonList(new 
ToolchainModel()));
-        executionRequest.setToolchains(toolchainModels);
-        when(session.getRequest()).thenReturn(executionRequest);
-
-        List<Toolchain> toolchains = toolchainManager.getToolchains(session, 
"unknown", null);
-
-        assertEquals(0, toolchains.size());
-        verify(logger).error("Missing toolchain factory for type: unknown. 
Possibly caused by misconfigured project.");
-    }
-
-    @Test
-    void testModelAndFactory() {
-        MavenSession session = mock(MavenSession.class);
-        MavenExecutionRequest executionRequest = new 
DefaultMavenExecutionRequest();
-        Map<String, List<ToolchainModel>> toolchainModels = new HashMap<>();
-        toolchainModels.put("basic", Arrays.asList(new ToolchainModel(), new 
ToolchainModel()));
-        toolchainModels.put("rare", Collections.singletonList(new 
ToolchainModel()));
-        executionRequest.setToolchains(toolchainModels);
-        when(session.getRequest()).thenReturn(executionRequest);
-
-        List<Toolchain> toolchains = toolchainManager.getToolchains(session, 
"rare", null);
-
-        assertEquals(1, toolchains.size());
-    }
-
-    @Test
-    void testModelsAndFactory() {
-        MavenSession session = mock(MavenSession.class);
-        MavenExecutionRequest executionRequest = new 
DefaultMavenExecutionRequest();
-        Map<String, List<ToolchainModel>> toolchainModels = new HashMap<>();
-        toolchainModels.put("basic", Arrays.asList(new ToolchainModel(), new 
ToolchainModel()));
-        toolchainModels.put("rare", Collections.singletonList(new 
ToolchainModel()));
-        executionRequest.setToolchains(toolchainModels);
-        when(session.getRequest()).thenReturn(executionRequest);
-
-        List<Toolchain> toolchains = toolchainManager.getToolchains(session, 
"basic", null);
-
-        assertEquals(2, toolchains.size());
-    }
-
-    @Test
-    void testRequirements() throws Exception {
-        MavenSession session = mock(MavenSession.class);
-        MavenExecutionRequest executionRequest = new 
DefaultMavenExecutionRequest();
-        Map<String, List<ToolchainModel>> toolchainModels = new HashMap<>();
-        toolchainModels.put("basic", Arrays.asList(new ToolchainModel(), new 
ToolchainModel()));
-        toolchainModels.put("rare", Collections.singletonList(new 
ToolchainModel()));
-        executionRequest.setToolchains(toolchainModels);
-        when(session.getRequest()).thenReturn(executionRequest);
-        ToolchainPrivate basicPrivate = mock(ToolchainPrivate.class);
-        when(basicPrivate.matchesRequirements(ArgumentMatchers.<String, 
String>anyMap()))
-                .thenReturn(false)
-                .thenReturn(true);
-        
when(toolchainFactory_basicType.createToolchain(isA(ToolchainModel.class)))
-                .thenReturn(basicPrivate);
-
-        List<Toolchain> toolchains =
-                toolchainManager.getToolchains(session, "basic", 
Collections.singletonMap("key", "value"));
-
-        assertEquals(1, toolchains.size());
-    }
-}
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultToolchainManager.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultToolchainManager.java
new file mode 100644
index 0000000000..cc2cb0360b
--- /dev/null
+++ 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultToolchainManager.java
@@ -0,0 +1,127 @@
+/*
+ * 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.impl;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Stream;
+
+import org.apache.maven.api.Project;
+import org.apache.maven.api.Session;
+import org.apache.maven.api.SessionData;
+import org.apache.maven.api.Toolchain;
+import org.apache.maven.api.annotations.Nonnull;
+import org.apache.maven.api.annotations.Nullable;
+import org.apache.maven.api.di.Inject;
+import org.apache.maven.api.di.Named;
+import org.apache.maven.api.di.Singleton;
+import org.apache.maven.api.services.Lookup;
+import org.apache.maven.api.services.ToolchainFactory;
+import org.apache.maven.api.services.ToolchainFactoryException;
+import org.apache.maven.api.services.ToolchainManager;
+import org.apache.maven.api.services.ToolchainManagerException;
+import org.apache.maven.api.toolchain.ToolchainModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Named
+@Singleton
+public class DefaultToolchainManager implements ToolchainManager {
+    private final Map<String, ToolchainFactory> factories;
+    private final Logger logger;
+
+    @Inject
+    public DefaultToolchainManager(Map<String, ToolchainFactory> factories) {
+        this(factories, null);
+    }
+
+    /**
+     * Used for tests only
+     */
+    protected DefaultToolchainManager(Map<String, ToolchainFactory> factories, 
Logger logger) {
+        this.factories = factories;
+        this.logger = logger != null ? logger : 
LoggerFactory.getLogger(DefaultToolchainManager.class);
+    }
+
+    @Nonnull
+    @Override
+    public List<Toolchain> getToolchains(
+            @Nonnull Session session, @Nonnull String type, @Nullable 
Map<String, String> requirements)
+            throws ToolchainManagerException {
+        ToolchainFactory factory = factories.get(Objects.requireNonNull(type, 
"type"));
+        if (factory == null) {
+            logger.error("Missing toolchain factory for type: " + type + ". 
Possibly caused by misconfigured project.");
+            return List.of();
+        }
+        return Stream.concat(
+                        session.getToolchains().stream()
+                                .filter(model -> Objects.equals(type, 
model.getType()))
+                                .map(this::createToolchain)
+                                .flatMap(Optional::stream),
+                        factory.createDefaultToolchain().stream())
+                .filter(toolchain -> requirements == null || 
toolchain.matchesRequirements(requirements))
+                .toList();
+    }
+
+    @Nonnull
+    @Override
+    public Optional<Toolchain> getToolchainFromBuildContext(@Nonnull Session 
session, @Nonnull String type)
+            throws ToolchainManagerException {
+        Map<String, Object> context = retrieveContext(session);
+        ToolchainModel model = (ToolchainModel) context.get("toolchain-" + 
type);
+        return Optional.ofNullable(model).flatMap(this::createToolchain);
+    }
+
+    @Override
+    public void storeToolchainToBuildContext(@Nonnull Session session, 
@Nonnull Toolchain toolchain) {
+        Map<String, Object> context = retrieveContext(session);
+        context.put("toolchain-" + toolchain.getType(), toolchain.getModel());
+    }
+
+    private Optional<Toolchain> createToolchain(ToolchainModel model) {
+        String type = Objects.requireNonNull(model.getType(), 
"model.getType()");
+        ToolchainFactory factory = factories.get(type);
+        if (factory != null) {
+            try {
+                return Optional.of(factory.createToolchain(model));
+            } catch (ToolchainFactoryException e) {
+                throw new ToolchainManagerException("Error creating toolchain 
of type " + type, e);
+            }
+        } else {
+            logger.error("Missing toolchain factory for type: " + type + ". 
Possibly caused by misconfigured project.");
+        }
+        return Optional.empty();
+    }
+
+    private static final SessionData.Key<ConcurrentHashMap<Project, 
ConcurrentHashMap<String, Object>>>
+            TOOLCHAIN_CONTEXT_KEY = (SessionData.Key) 
SessionData.key(ConcurrentHashMap.class, "toolchain-context");
+
+    protected Map<String, Object> retrieveContext(Session session) {
+        Optional<Project> current = 
session.getService(Lookup.class).lookupOptional(Project.class);
+        if (current.isPresent()) {
+            var map = session.getData().computeIfAbsent(TOOLCHAIN_CONTEXT_KEY, 
ConcurrentHashMap::new);
+            return map.computeIfAbsent(current.get(), p -> new 
ConcurrentHashMap<>());
+        }
+        return new HashMap<>();
+    }
+}
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
index 445f33cfcd..aa51f1c03f 100644
--- 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
+++ 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
@@ -177,7 +177,7 @@ public DefaultModelBuilder(
             DependencyManagementImporter dependencyManagementImporter,
             PluginConfigurationExpander pluginConfigurationExpander,
             ModelVersionParser versionParser,
-            List<ModelTransformer> transformers,
+            @Nullable List<ModelTransformer> transformers,
             ModelResolver modelResolver,
             Interpolator interpolator,
             PathTranslator pathTranslator,
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelProcessor.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelProcessor.java
index 9cea972079..425563789c 100644
--- 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelProcessor.java
+++ 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelProcessor.java
@@ -28,6 +28,7 @@
 import java.util.Objects;
 import java.util.Optional;
 
+import org.apache.maven.api.annotations.Nullable;
 import org.apache.maven.api.di.Inject;
 import org.apache.maven.api.di.Named;
 import org.apache.maven.api.di.Singleton;
@@ -71,7 +72,7 @@ public class DefaultModelProcessor implements ModelProcessor {
     private final List<ModelParser> modelParsers;
 
     @Inject
-    public DefaultModelProcessor(ModelXmlFactory modelXmlFactory, 
List<ModelParser> modelParsers) {
+    public DefaultModelProcessor(ModelXmlFactory modelXmlFactory, @Nullable 
List<ModelParser> modelParsers) {
         this.modelXmlFactory = modelXmlFactory;
         this.modelParsers = modelParsers;
     }
diff --git 
a/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultToolchainManagerTest.java
 
b/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultToolchainManagerTest.java
new file mode 100644
index 0000000000..7ebc8f978e
--- /dev/null
+++ 
b/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultToolchainManagerTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.maven.api.Project;
+import org.apache.maven.api.Session;
+import org.apache.maven.api.SessionData;
+import org.apache.maven.api.Toolchain;
+import org.apache.maven.api.services.Lookup;
+import org.apache.maven.api.services.ToolchainFactory;
+import org.apache.maven.api.toolchain.ToolchainModel;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class DefaultToolchainManagerTest {
+
+    @Mock
+    private Session session;
+
+    @Mock
+    private Lookup lookup;
+
+    @Mock
+    private Project project;
+
+    @Mock
+    private ToolchainFactory jdkFactory;
+
+    @Mock
+    private Toolchain mockToolchain;
+
+    private ToolchainModel toolchainModel;
+
+    private DefaultToolchainManager manager;
+
+    @BeforeEach
+    void setUp() {
+        manager = new DefaultToolchainManager(Map.of("jdk", jdkFactory));
+    }
+
+    @Test
+    void getToolchains_WithValidTypeAndRequirements() {
+        toolchainModel = ToolchainModel.newBuilder().type("jdk").build();
+        when(session.getToolchains()).thenReturn(List.of(toolchainModel));
+        
when(jdkFactory.createToolchain(toolchainModel)).thenReturn(mockToolchain);
+        when(jdkFactory.createDefaultToolchain()).thenReturn(Optional.empty());
+        when(mockToolchain.matchesRequirements(any())).thenReturn(true);
+
+        List<Toolchain> result = manager.getToolchains(session, "jdk", 
Map.of("version", "11"));
+
+        assertEquals(1, result.size());
+        assertEquals(mockToolchain, result.get(0));
+    }
+
+    @Test
+    void getToolchains_WithInvalidType() {
+        List<Toolchain> result = manager.getToolchains(session, "invalid", 
null);
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    void storeAndRetrieveToolchainFromBuildContext() {
+        Map<String, Object> context = new ConcurrentHashMap<>();
+        SessionData data = mock(SessionData.class);
+        toolchainModel = ToolchainModel.newBuilder().type("jdk").build();
+        when(session.getService(Lookup.class)).thenReturn(lookup);
+        
when(lookup.lookupOptional(Project.class)).thenReturn(Optional.of(project));
+        when(session.getData()).thenReturn(data);
+        when(data.computeIfAbsent(any(), any())).thenReturn(context);
+        when(mockToolchain.getType()).thenReturn("jdk");
+        when(mockToolchain.getModel()).thenReturn(toolchainModel);
+        
when(jdkFactory.createToolchain(any(ToolchainModel.class))).thenReturn(mockToolchain);
+
+        manager.storeToolchainToBuildContext(session, mockToolchain);
+        Optional<Toolchain> result = 
manager.getToolchainFromBuildContext(session, "jdk");
+
+        assertTrue(result.isPresent());
+        assertEquals(mockToolchain, result.get());
+    }
+
+    @Test
+    void retrieveContext_WithoutProject() {
+        when(session.getService(Lookup.class)).thenReturn(lookup);
+        
when(lookup.lookupOptional(Project.class)).thenReturn(Optional.empty());
+
+        assertTrue(manager.retrieveContext(session).isEmpty());
+    }
+
+    @Test
+    void getToolchains_WithNullType() {
+        assertThrows(NullPointerException.class, () -> 
manager.getToolchains(session, null, null));
+    }
+}
diff --git 
a/impl/maven-impl/src/test/java/org/apache/maven/impl/standalone/ApiRunner.java 
b/impl/maven-impl/src/test/java/org/apache/maven/impl/standalone/ApiRunner.java
index 43cefbc867..50e0db5859 100644
--- 
a/impl/maven-impl/src/test/java/org/apache/maven/impl/standalone/ApiRunner.java
+++ 
b/impl/maven-impl/src/test/java/org/apache/maven/impl/standalone/ApiRunner.java
@@ -21,6 +21,7 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.time.Instant;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -42,6 +43,7 @@
 import org.apache.maven.api.Session;
 import org.apache.maven.api.Type;
 import org.apache.maven.api.Version;
+import org.apache.maven.api.annotations.Nonnull;
 import org.apache.maven.api.annotations.Nullable;
 import org.apache.maven.api.di.Provides;
 import org.apache.maven.api.di.SessionScoped;
@@ -57,6 +59,7 @@
 import org.apache.maven.api.services.TypeRegistry;
 import org.apache.maven.api.settings.Settings;
 import org.apache.maven.api.spi.TypeProvider;
+import org.apache.maven.api.toolchain.ToolchainModel;
 import org.apache.maven.di.Injector;
 import org.apache.maven.di.Key;
 import org.apache.maven.di.impl.DIException;
@@ -140,6 +143,12 @@ public Settings getSettings() {
             return Settings.newInstance();
         }
 
+        @Override
+        @Nonnull
+        public Collection<ToolchainModel> getToolchains() {
+            return List.of();
+        }
+
         @Override
         public Map<String, String> getUserProperties() {
             return Map.of();
diff --git 
a/its/core-it-support/core-it-plugins/maven-it-plugin-toolchain/pom.xml 
b/its/core-it-support/core-it-plugins/maven-it-plugin-toolchain/pom.xml
index abae54cde9..0d0c19b077 100644
--- a/its/core-it-support/core-it-plugins/maven-it-plugin-toolchain/pom.xml
+++ b/its/core-it-support/core-it-plugins/maven-it-plugin-toolchain/pom.xml
@@ -44,7 +44,7 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.maven</groupId>
-      <artifactId>maven-core</artifactId>
+      <artifactId>maven-compat</artifactId>
       <scope>provided</scope>
     </dependency>
   </dependencies>
diff --git a/its/core-it-support/core-it-toolchain/pom.xml 
b/its/core-it-support/core-it-toolchain/pom.xml
index eb21cdbe1a..06e62f0ec1 100644
--- a/its/core-it-support/core-it-toolchain/pom.xml
+++ b/its/core-it-support/core-it-toolchain/pom.xml
@@ -31,9 +31,29 @@ under the License.
   <name>Maven IT Toolchain</name>
 
   <dependencies>
+    <dependency>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.apache.maven</groupId>
-      <artifactId>maven-core</artifactId>
+      <artifactId>maven-compat</artifactId>
     </dependency>
   </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.eclipse.sisu</groupId>
+        <artifactId>sisu-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>main-index</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git 
a/its/core-it-support/core-it-toolchain/src/main/java/org/apache/maven/coreit/toolchain/CoreItToolchainFactory.java
 
b/its/core-it-support/core-it-toolchain/src/main/java/org/apache/maven/coreit/toolchain/CoreItToolchainFactory.java
index 004ac24dd7..0b203500a6 100644
--- 
a/its/core-it-support/core-it-toolchain/src/main/java/org/apache/maven/coreit/toolchain/CoreItToolchainFactory.java
+++ 
b/its/core-it-support/core-it-toolchain/src/main/java/org/apache/maven/coreit/toolchain/CoreItToolchainFactory.java
@@ -18,7 +18,8 @@
  */
 package org.apache.maven.coreit.toolchain;
 
-import org.apache.maven.toolchain.MisconfiguredToolchainException;
+import javax.inject.Named;
+
 import org.apache.maven.toolchain.ToolchainFactory;
 import org.apache.maven.toolchain.ToolchainPrivate;
 import org.apache.maven.toolchain.model.ToolchainModel;
@@ -26,13 +27,14 @@
 /**
  * @author Benjamin Bentmann
  */
+@Named("coreit")
 public class CoreItToolchainFactory implements ToolchainFactory {
 
     public ToolchainPrivate createDefaultToolchain() {
         return null;
     }
 
-    public ToolchainPrivate createToolchain(ToolchainModel model) throws 
MisconfiguredToolchainException {
+    public ToolchainPrivate createToolchain(ToolchainModel model) {
         if (model == null) {
             return null;
         }
diff --git 
a/its/core-it-support/core-it-toolchain/src/main/resources/META-INF/plexus/components.xml
 
b/its/core-it-support/core-it-toolchain/src/main/resources/META-INF/plexus/components.xml
deleted file mode 100644
index 3a31c50c1c..0000000000
--- 
a/its/core-it-support/core-it-toolchain/src/main/resources/META-INF/plexus/components.xml
+++ /dev/null
@@ -1,29 +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.
--->
-
-<component-set>
-  <components>
-    <component>
-      <role>org.apache.maven.toolchain.ToolchainFactory</role>
-      <role-hint>coreit</role-hint>
-      
<implementation>org.apache.maven.coreit.toolchain.CoreItToolchainFactory</implementation>
-      <instantiation-strategy>singleton</instantiation-strategy>
-    </component>
-  </components>
-</component-set>


Reply via email to