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

commit 8e4041759bd7cbd5dd807577b66f9f79252ef33b
Author: Guillaume Nodet <gno...@gmail.com>
AuthorDate: Wed Jan 29 14:50:02 2025 +0100

    [MNG-8540] Add global caching in the session
---
 .../maven/internal/impl/DefaultProjectBuilder.java |   7 ++
 .../apache/maven/internal/impl/DefaultSession.java |   1 +
 .../impl/ConsumerPomBuilderTest.java               |  39 --------
 .../maven/api/services/model/ModelResolver.java    |  89 +++++++++++------
 .../org/apache/maven/impl/AbstractSession.java     |  76 +++++++++++++++
 .../apache/maven/impl/DefaultArtifactResolver.java |   5 +
 .../maven/impl/DefaultVersionRangeResolver.java    |   5 +
 .../apache/maven/impl/DefaultVersionResolver.java  |   4 +
 .../org/apache/maven/impl/InternalSession.java     |  17 ++++
 .../maven/impl/model/DefaultModelBuilder.java      |  87 +----------------
 .../maven/impl/resolver/DefaultModelResolver.java  | 107 ++++++++++++---------
 11 files changed, 239 insertions(+), 198 deletions(-)

diff --git 
a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java
 
b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java
index 06690ec1b5..b51241642a 100644
--- 
a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java
+++ 
b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java
@@ -42,6 +42,7 @@
 import org.apache.maven.api.services.Source;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.impl.DefaultDependencyResolverResult;
+import org.apache.maven.impl.InternalSession;
 import org.apache.maven.impl.MappedCollection;
 import org.apache.maven.impl.RequestTraceHelper;
 import org.apache.maven.model.building.ModelProblem;
@@ -67,6 +68,12 @@ public 
DefaultProjectBuilder(org.apache.maven.project.ProjectBuilder builder) {
     @Override
     public ProjectBuilderResult build(ProjectBuilderRequest request)
             throws ProjectBuilderException, IllegalArgumentException {
+        InternalSession session = InternalSession.from(request.getSession());
+        return session.request(request, this::doBuild);
+    }
+
+    protected ProjectBuilderResult doBuild(ProjectBuilderRequest request)
+            throws ProjectBuilderException, IllegalArgumentException {
         InternalMavenSession session = 
InternalMavenSession.from(request.getSession());
         RequestTraceHelper.ResolverTrace trace = 
RequestTraceHelper.enter(request.getSession(), request);
         try {
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 f87c95310e..d105759853 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
@@ -182,6 +182,7 @@ public Map<String, Object> getPluginContext(Project 
project) {
         }
     }
 
+    @Override
     protected Session newSession(RepositorySystemSession repoSession, 
List<RemoteRepository> repositories) {
         final MavenSession ms = nonNull(getMavenSession());
         final MavenSession mss;
diff --git 
a/impl/maven-core/src/test/java/org/apache/maven/internal/transformation/impl/ConsumerPomBuilderTest.java
 
b/impl/maven-core/src/test/java/org/apache/maven/internal/transformation/impl/ConsumerPomBuilderTest.java
index a5ff690b9a..23d94c7e85 100644
--- 
a/impl/maven-core/src/test/java/org/apache/maven/internal/transformation/impl/ConsumerPomBuilderTest.java
+++ 
b/impl/maven-core/src/test/java/org/apache/maven/internal/transformation/impl/ConsumerPomBuilderTest.java
@@ -24,12 +24,10 @@
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.function.Consumer;
 
 import org.apache.maven.api.DependencyCoordinates;
 import org.apache.maven.api.Node;
 import org.apache.maven.api.PathScope;
-import org.apache.maven.api.RemoteRepository;
 import org.apache.maven.api.Session;
 import org.apache.maven.api.SessionData;
 import org.apache.maven.api.model.Model;
@@ -37,11 +35,7 @@
 import org.apache.maven.api.services.DependencyResolverResult;
 import org.apache.maven.api.services.ModelBuilder;
 import org.apache.maven.api.services.ModelBuilderRequest;
-import org.apache.maven.api.services.ModelSource;
 import org.apache.maven.api.services.Sources;
-import org.apache.maven.api.services.model.ModelResolver;
-import org.apache.maven.api.services.model.ModelResolverException;
-import org.apache.maven.di.Injector;
 import org.apache.maven.execution.MavenExecutionRequest;
 import org.apache.maven.impl.DefaultArtifactCoordinatesFactory;
 import org.apache.maven.impl.DefaultDependencyCoordinatesFactory;
@@ -52,7 +46,6 @@
 import org.apache.maven.internal.impl.InternalMavenSession;
 import org.apache.maven.internal.transformation.AbstractRepositoryTestCase;
 import org.apache.maven.project.MavenProject;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
 
@@ -67,15 +60,6 @@ public class ConsumerPomBuilderTest extends 
AbstractRepositoryTestCase {
     @Inject
     ModelBuilder modelBuilder;
 
-    @BeforeEach
-    void setupTransformerContext() throws Exception {
-        // We need bind the model resolver explicitly to avoid going to maven 
central
-        
getContainer().lookup(Injector.class).bindImplicit(MyModelResolver.class);
-        InternalSession iSession = InternalSession.from(session);
-        // set up the model resolver
-        iSession.getData().set(SessionData.key(ModelResolver.class), new 
MyModelResolver());
-    }
-
     @Override
     protected List<Object> getSessionServices() {
         List<Object> services = new ArrayList<>(super.getSessionServices());
@@ -152,27 +136,4 @@ void testSimpleConsumer() throws Exception {
         assertNotNull(model);
         assertTrue(model.getProfiles().isEmpty());
     }
-
-    static class MyModelResolver implements ModelResolver {
-        @Override
-        public ModelSource resolveModel(
-                Session session,
-                List<RemoteRepository> repositories,
-                String groupId,
-                String artifactId,
-                String version,
-                String classifier,
-                Consumer<String> resolvedVersion)
-                throws ModelResolverException {
-            String id = groupId + ":" + artifactId + ":" + version;
-            if (id.startsWith("org.sonatype.mavenbook.multi:parent:")) {
-                return 
Sources.buildSource(Paths.get("src/test/resources/consumer/simple/pom.xml"));
-            } else if 
(id.startsWith("org.sonatype.mavenbook.multi:simple-parent:")) {
-                return 
Sources.buildSource(Paths.get("src/test/resources/consumer/simple/simple-parent/pom.xml"));
-            } else if (id.startsWith("org.my.group:parent:")) {
-                return 
Sources.buildSource(Paths.get("src/test/resources/consumer/trivial/pom.xml"));
-            }
-            return null;
-        }
-    }
 }
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/api/services/model/ModelResolver.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/api/services/model/ModelResolver.java
index aa8ffdbfe8..0a7cbb621c 100644
--- 
a/impl/maven-impl/src/main/java/org/apache/maven/api/services/model/ModelResolver.java
+++ 
b/impl/maven-impl/src/main/java/org/apache/maven/api/services/model/ModelResolver.java
@@ -19,8 +19,8 @@
 package org.apache.maven.api.services.model;
 
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Consumer;
 
 import org.apache.maven.api.RemoteRepository;
 import org.apache.maven.api.Service;
@@ -30,6 +30,9 @@
 import org.apache.maven.api.model.Dependency;
 import org.apache.maven.api.model.Parent;
 import org.apache.maven.api.services.ModelSource;
+import org.apache.maven.api.services.Request;
+import org.apache.maven.api.services.RequestTrace;
+import org.apache.maven.api.services.Result;
 
 /**
  * Resolves a POM from its coordinates.
@@ -47,21 +50,12 @@ public interface ModelResolver extends Service {
      * @throws ModelResolverException If the POM could not be resolved from 
any configured repository.
      */
     @Nonnull
-    default ModelSource resolveModel(
+    ModelSource resolveModel(
             @Nonnull Session session,
             @Nullable List<RemoteRepository> repositories,
             @Nonnull Parent parent,
             @Nonnull AtomicReference<Parent> modified)
-            throws ModelResolverException {
-        return resolveModel(
-                session,
-                repositories,
-                parent.getGroupId(),
-                parent.getArtifactId(),
-                parent.getVersion(),
-                null,
-                version -> modified.set(parent.withVersion(version)));
-    }
+            throws ModelResolverException;
 
     /**
      * Tries to resolve the POM for the specified dependency coordinates 
possibly updating {@code dependency}.
@@ -74,30 +68,71 @@ default ModelSource resolveModel(
      * @throws ModelResolverException If the POM could not be resolved from 
any configured repository.
      */
     @Nonnull
-    default ModelSource resolveModel(
+    ModelSource resolveModel(
             @Nonnull Session session,
             @Nullable List<RemoteRepository> repositories,
             @Nonnull Dependency dependency,
             @Nonnull AtomicReference<Dependency> modified)
-            throws ModelResolverException {
-        return resolveModel(
-                session,
-                repositories,
-                dependency.getGroupId(),
-                dependency.getArtifactId(),
-                dependency.getVersion(),
-                dependency.getClassifier(),
-                version -> modified.set(dependency.withVersion(version)));
-    }
+            throws ModelResolverException;
 
     @Nonnull
-    ModelSource resolveModel(
+    ModelResolverResult resolveModel(@Nonnull ModelResolverRequest request) 
throws ModelResolverException;
+
+    record ModelResolverRequest(
             @Nonnull Session session,
+            @Nullable RequestTrace trace,
             @Nullable List<RemoteRepository> repositories,
             @Nonnull String groupId,
             @Nonnull String artifactId,
             @Nonnull String version,
-            @Nullable String classifier,
-            @Nonnull Consumer<String> resolvedVersion)
-            throws ModelResolverException;
+            @Nullable String classifier)
+            implements Request<Session> {
+        @Nonnull
+        @Override
+        public Session getSession() {
+            return session;
+        }
+
+        @Nullable
+        @Override
+        public RequestTrace getTrace() {
+            return trace;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            return o instanceof ModelResolverRequest that
+                    && repositories == that.repositories
+                    && Objects.equals(groupId, that.groupId)
+                    && Objects.equals(artifactId, that.artifactId)
+                    && Objects.equals(version, that.version)
+                    && Objects.equals(classifier, that.classifier);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(repositories, groupId, artifactId, version, 
classifier);
+        }
+
+        @Override
+        @Nonnull
+        public String toString() {
+            return getClass().getSimpleName() + "[" + "repositories="
+                    + repositories + ", groupId="
+                    + groupId
+                    + ", artifactId=" + artifactId
+                    + ", version=" + version
+                    + ", classifier=" + classifier
+                    + ']';
+        }
+    }
+
+    record ModelResolverResult(ModelResolverRequest request, ModelSource 
source, String version)
+            implements Result<ModelResolverRequest> {
+        @Nonnull
+        @Override
+        public ModelResolverRequest getRequest() {
+            return request;
+        }
+    }
 }
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/AbstractSession.java 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/AbstractSession.java
index 117b81fa45..0f511ae09e 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/AbstractSession.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/AbstractSession.java
@@ -31,6 +31,7 @@
 import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
@@ -84,7 +85,9 @@
 import org.apache.maven.api.services.PathScopeRegistry;
 import org.apache.maven.api.services.ProjectScopeRegistry;
 import org.apache.maven.api.services.RepositoryFactory;
+import org.apache.maven.api.services.Request;
 import org.apache.maven.api.services.RequestTrace;
+import org.apache.maven.api.services.Result;
 import org.apache.maven.api.services.TypeRegistry;
 import org.apache.maven.api.services.VersionParser;
 import org.apache.maven.api.services.VersionRangeResolver;
@@ -116,6 +119,8 @@ public abstract class AbstractSession implements 
InternalSession {
     private final Map<org.eclipse.aether.graph.Dependency, Dependency> 
allDependencies =
             Collections.synchronizedMap(new WeakHashMap<>());
 
+    private final Map<Object, CachingSupplier<?, ?>> requestCache;
+
     static {
         TransferResource.setClock(MonotonicClock.get());
     }
@@ -130,6 +135,77 @@ public AbstractSession(
         this.repositorySystem = repositorySystem;
         this.repositories = getRepositories(repositories, 
resolverRepositories);
         this.lookup = lookup;
+        this.requestCache = new ConcurrentHashMap<>();
+    }
+
+    @Override
+    public <REQ extends Request<?>, REP extends Result<REQ>> REP request(REQ 
req, Function<REQ, REP> supplier) {
+        if (requestCache == null) {
+            return supplier.apply(req);
+        }
+        @SuppressWarnings("all")
+        CachingSupplier<REQ, REP> cs =
+                (CachingSupplier) requestCache.computeIfAbsent(req, r -> new 
CachingSupplier<>(supplier));
+        return cs.apply(req);
+    }
+
+    /**
+     * A caching supplier wrapper that caches results and exceptions from the 
underlying supplier.
+     * Used internally to cache expensive computations in the session.
+     *
+     * @param <REQ> The request type
+     * @param <REP> The response type
+     */
+    static class CachingSupplier<REQ, REP> implements Function<REQ, REP> {
+        final Function<REQ, REP> supplier;
+        volatile Object value;
+
+        CachingSupplier(Function<REQ, REP> supplier) {
+            this.supplier = supplier;
+        }
+
+        @Override
+        @SuppressWarnings({"unchecked", "checkstyle:InnerAssignment"})
+        public REP apply(REQ req) {
+            Object v;
+            if ((v = value) == null) {
+                synchronized (this) {
+                    if ((v = value) == null) {
+                        try {
+                            v = value = supplier.apply(req);
+                        } catch (Exception e) {
+                            v = value = new CachingSupplier.AltRes(e);
+                        }
+                    }
+                }
+            }
+            if (v instanceof CachingSupplier.AltRes altRes) {
+                uncheckedThrow(altRes.t);
+            }
+            return (REP) v;
+        }
+
+        /**
+         * Special holder class for exceptions that occur during supplier 
execution.
+         * Allows caching and re-throwing of exceptions on subsequent calls.
+         */
+        static class AltRes {
+            final Throwable t;
+
+            /**
+             * Creates a new AltRes with the given throwable.
+             *
+             * @param t The throwable to store
+             */
+            AltRes(Throwable t) {
+                this.t = t;
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    static <T extends Throwable> void uncheckedThrow(Throwable t) throws T {
+        throw (T) t; // rely on vacuous cast
     }
 
     @Override
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultArtifactResolver.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultArtifactResolver.java
index b83d649206..8331100d23 100644
--- 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultArtifactResolver.java
+++ 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultArtifactResolver.java
@@ -50,6 +50,11 @@ public class DefaultArtifactResolver implements 
ArtifactResolver {
     public ArtifactResolverResult resolve(ArtifactResolverRequest request)
             throws ArtifactResolverException, IllegalArgumentException {
         nonNull(request, "request");
+        InternalSession session = InternalSession.from(request.getSession());
+        return session.request(request, this::doResolve);
+    }
+
+    protected ArtifactResolverResult doResolve(ArtifactResolverRequest 
request) {
         InternalSession session = InternalSession.from(request.getSession());
         RequestTraceHelper.ResolverTrace trace = 
RequestTraceHelper.enter(session, request);
         try {
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultVersionRangeResolver.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultVersionRangeResolver.java
index a189d4328a..b3ef4d59b8 100644
--- 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultVersionRangeResolver.java
+++ 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultVersionRangeResolver.java
@@ -57,7 +57,12 @@ public VersionRangeResolverResult 
resolve(VersionRangeResolverRequest request)
             throws VersionRangeResolverException {
         requireNonNull(request, "request");
         InternalSession session = InternalSession.from(request.getSession());
+        return session.request(request, this::doResolve);
+    }
 
+    public VersionRangeResolverResult doResolve(VersionRangeResolverRequest 
request)
+            throws VersionRangeResolverException {
+        InternalSession session = InternalSession.from(request.getSession());
         RequestTraceHelper.ResolverTrace trace = 
RequestTraceHelper.enter(session, request);
         try {
             VersionRangeResult res = repositorySystem.resolveVersionRange(
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultVersionResolver.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultVersionResolver.java
index a9b4ba4748..ff07e5bb26 100644
--- 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultVersionResolver.java
+++ 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultVersionResolver.java
@@ -52,7 +52,11 @@ public DefaultVersionResolver(RepositorySystem 
repositorySystem) {
     public VersionResolverResult resolve(VersionResolverRequest request) 
throws VersionResolverException {
         nonNull(request, "request");
         InternalSession session = InternalSession.from(request.getSession());
+        return session.request(request, this::doResolve);
+    }
 
+    protected VersionResolverResult doResolve(VersionResolverRequest request) 
throws VersionResolverException {
+        InternalSession session = InternalSession.from(request.getSession());
         RequestTraceHelper.ResolverTrace trace = 
RequestTraceHelper.enter(session, request);
         try {
             VersionRequest req = new VersionRequest(
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/InternalSession.java 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/InternalSession.java
index fe8a44715b..63c6fbcfc1 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/InternalSession.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/InternalSession.java
@@ -20,6 +20,7 @@
 
 import java.util.Collection;
 import java.util.List;
+import java.util.function.Function;
 
 import org.apache.maven.api.Artifact;
 import org.apache.maven.api.ArtifactCoordinates;
@@ -31,7 +32,9 @@
 import org.apache.maven.api.Session;
 import org.apache.maven.api.annotations.Nonnull;
 import org.apache.maven.api.annotations.Nullable;
+import org.apache.maven.api.services.Request;
 import org.apache.maven.api.services.RequestTrace;
+import org.apache.maven.api.services.Result;
 import org.eclipse.aether.RepositorySystem;
 import org.eclipse.aether.RepositorySystemSession;
 
@@ -53,6 +56,20 @@ static void 
associate(org.eclipse.aether.RepositorySystemSession rsession, Sessi
         }
     }
 
+    /**
+     * Executes and optionally caches a request using the provided supplier 
function. If caching is enabled
+     * for this session, the result will be cached and subsequent identical 
requests will return the cached
+     * value without re-executing the supplier.
+     *
+     * @param <REQ> The request type
+     * @param <REP> The response type
+     * @param req The request object used as the cache key
+     * @param supplier The function to execute and cache the result
+     * @return The result from the supplier (either fresh or cached)
+     * @throws RuntimeException Any exception thrown by the supplier will be 
cached and re-thrown on subsequent calls
+     */
+    <REQ extends Request<?>, REP extends Result<REQ>> REP request(REQ req, 
Function<REQ, REP> supplier);
+
     RemoteRepository 
getRemoteRepository(org.eclipse.aether.repository.RemoteRepository repository);
 
     Node getNode(org.eclipse.aether.graph.DependencyNode node);
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 a39f981a13..2809c0b19c 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
@@ -41,7 +41,6 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Consumer;
 import java.util.function.Supplier;
 import java.util.function.UnaryOperator;
 import java.util.regex.Matcher;
@@ -1049,8 +1048,7 @@ Model resolveAndReadParentExternally(Model childModel, 
DefaultProfileActivationC
                 modelSource = resolveReactorModel(parent.getGroupId(), 
parent.getArtifactId(), parent.getVersion());
                 if (modelSource == null) {
                     AtomicReference<Parent> modified = new AtomicReference<>();
-                    modelSource = new CachingModelResolver()
-                            .resolveModel(request.getSession(), repositories, 
parent, modified);
+                    modelSource = 
modelResolver.resolveModel(request.getSession(), repositories, parent, 
modified);
                     if (modified.get() != null) {
                         parent = modified.get();
                     }
@@ -1721,8 +1719,8 @@ private Model doLoadDependencyManagement(
             try {
                 importSource = resolveReactorModel(groupId, artifactId, 
version);
                 if (importSource == null) {
-                    importSource = new CachingModelResolver()
-                            .resolveModel(request.getSession(), repositories, 
dependency, new AtomicReference<>());
+                    importSource = modelResolver.resolveModel(
+                            request.getSession(), repositories, dependency, 
new AtomicReference<>());
                 }
             } catch (ModelBuilderException | ModelResolverException e) {
                 StringBuilder buffer = new StringBuilder(256);
@@ -1815,85 +1813,6 @@ boolean isBuildRequest() {
         boolean isBuildRequestWithActivation() {
             return request.getRequestType() != 
ModelBuilderRequest.RequestType.BUILD_CONSUMER;
         }
-
-        record ModelResolverResult(ModelSource source, String resolvedVersion) 
{}
-
-        class CachingModelResolver implements ModelResolver {
-            @Override
-            public ModelSource resolveModel(
-                    Session session,
-                    List<RemoteRepository> repositories,
-                    Parent parent,
-                    AtomicReference<Parent> modified)
-                    throws ModelResolverException {
-                ModelResolverResult result = cache.computeIfAbsent(
-                        repositories,
-                        parent.getGroupId(),
-                        parent.getArtifactId(),
-                        parent.getVersion(),
-                        null,
-                        MODEL,
-                        () -> {
-                            AtomicReference<Parent> mod = new 
AtomicReference<>();
-                            ModelSource res = 
modelResolver.resolveModel(session, repositories, parent, mod);
-                            return new ModelResolverResult(
-                                    res, mod.get() != null ? 
mod.get().getVersion() : null);
-                        });
-                if (result.resolvedVersion != null && modified != null) {
-                    modified.set(parent.withVersion(result.resolvedVersion));
-                }
-                return result.source;
-            }
-
-            @Override
-            public ModelSource resolveModel(
-                    Session session,
-                    List<RemoteRepository> repositories,
-                    Dependency dependency,
-                    AtomicReference<Dependency> modified)
-                    throws ModelResolverException {
-                ModelResolverResult result = cache.computeIfAbsent(
-                        repositories,
-                        dependency.getGroupId(),
-                        dependency.getArtifactId(),
-                        dependency.getVersion(),
-                        dependency.getClassifier(),
-                        MODEL,
-                        () -> {
-                            AtomicReference<Dependency> mod = new 
AtomicReference<>();
-                            ModelSource res = 
modelResolver.resolveModel(session, repositories, dependency, mod);
-                            return new ModelResolverResult(
-                                    res, mod.get() != null ? 
mod.get().getVersion() : null);
-                        });
-                if (result.resolvedVersion != null && modified != null) {
-                    
modified.set(dependency.withVersion(result.resolvedVersion));
-                }
-                return result.source;
-            }
-
-            @Override
-            public ModelSource resolveModel(
-                    Session session,
-                    List<RemoteRepository> repositories,
-                    String groupId,
-                    String artifactId,
-                    String version,
-                    String classifier,
-                    Consumer<String> resolvedVersion)
-                    throws ModelResolverException {
-                ModelResolverResult result =
-                        cache.computeIfAbsent(repositories, groupId, 
artifactId, version, classifier, MODEL, () -> {
-                            AtomicReference<String> mod = new 
AtomicReference<>();
-                            ModelSource res = modelResolver.resolveModel(
-                                    session, repositories, groupId, 
artifactId, version, classifier, mod::set);
-                            return new ModelResolverResult(res, mod.get());
-                        });
-                if (result.resolvedVersion != null) {
-                    resolvedVersion.accept(result.resolvedVersion);
-                }
-                return result.source;
-            }
-        }
     }
 
     @SuppressWarnings("deprecation")
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/DefaultModelResolver.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/DefaultModelResolver.java
index 69bf46c759..0abee8de30 100644
--- 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/DefaultModelResolver.java
+++ 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/DefaultModelResolver.java
@@ -21,7 +21,6 @@
 import java.nio.file.Path;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
 import org.apache.maven.api.ArtifactCoordinates;
@@ -41,6 +40,8 @@
 import org.apache.maven.api.services.VersionRangeResolverException;
 import org.apache.maven.api.services.model.ModelResolver;
 import org.apache.maven.api.services.model.ModelResolverException;
+import org.apache.maven.impl.InternalSession;
+import org.apache.maven.impl.RequestTraceHelper;
 
 /**
  * A model resolver to assist building of dependency POMs.
@@ -59,16 +60,21 @@ public ModelSource resolveModel(
             @Nonnull Parent parent,
             @Nonnull AtomicReference<Parent> modified)
             throws ModelResolverException {
-        return resolveModel(
-                session,
-                repositories,
-                parent.getGroupId(),
-                parent.getArtifactId(),
-                parent.getVersion(),
-                "parent",
-                null,
+        ModelResolverResult result = resolveModel(
+                new ModelResolverRequest(
+                        session,
+                        null,
+                        repositories,
+                        parent.getGroupId(),
+                        parent.getArtifactId(),
+                        parent.getVersion(),
+                        null),
                 parent.getLocation("version"),
-                version -> modified.set(parent.withVersion(version)));
+                "parent");
+        if (result.version() != null) {
+            modified.set(parent.withVersion(result.version()));
+        }
+        return result.source();
     }
 
     @Nonnull
@@ -78,44 +84,46 @@ public ModelSource resolveModel(
             @Nonnull Dependency dependency,
             @Nonnull AtomicReference<Dependency> modified)
             throws ModelResolverException {
-        return resolveModel(
-                session,
-                repositories,
-                dependency.getGroupId(),
-                dependency.getArtifactId(),
-                dependency.getVersion(),
-                "dependency",
-                dependency.getClassifier(),
+        ModelResolverResult result = resolveModel(
+                new ModelResolverRequest(
+                        session,
+                        null,
+                        repositories,
+                        dependency.getGroupId(),
+                        dependency.getArtifactId(),
+                        dependency.getVersion(),
+                        dependency.getClassifier()),
                 dependency.getLocation("version"),
-                version -> modified.set(dependency.withVersion(version)));
+                "dependency");
+        if (result.version() != null) {
+            modified.set(dependency.withVersion(result.version()));
+        }
+        return result.source();
     }
 
+    @Nonnull
     @Override
-    public ModelSource resolveModel(
-            @Nonnull Session session,
-            @Nullable List<RemoteRepository> repositories,
-            @Nonnull String groupId,
-            @Nonnull String artifactId,
-            @Nonnull String version,
-            @Nullable String classifier,
-            @Nonnull Consumer<String> resolvedVersion)
+    public ModelResolverResult resolveModel(@Nonnull ModelResolverRequest 
request) throws ModelResolverException {
+        return resolveModel(request, null, null);
+    }
+
+    public ModelResolverResult resolveModel(
+            @Nonnull ModelResolverRequest request, InputLocation location, 
String modelType)
             throws ModelResolverException {
-        return resolveModel(
-                session, repositories, groupId, artifactId, version, null, 
classifier, null, resolvedVersion);
+        return InternalSession.from(request.session()).request(request, r -> 
doResolveModel(r, location, modelType));
     }
 
-    @SuppressWarnings("checkstyle:ParameterNumber")
-    public ModelSource resolveModel(
-            Session session,
-            List<RemoteRepository> repositories,
-            String groupId,
-            String artifactId,
-            String version,
-            String type,
-            String classifier,
-            InputLocation location,
-            Consumer<String> resolvedVersion)
+    public ModelResolverResult doResolveModel(
+            @Nonnull ModelResolverRequest request, InputLocation location, 
String modelType)
             throws ModelResolverException {
+        Session session = request.session();
+        String groupId = request.groupId();
+        String artifactId = request.artifactId();
+        String version = request.version();
+        String classifier = request.classifier();
+        List<RemoteRepository> repositories = request.repositories();
+
+        RequestTraceHelper.ResolverTrace trace = 
RequestTraceHelper.enter(session, request);
         try {
             ArtifactCoordinates coords =
                     session.createArtifactCoordinates(groupId, artifactId, 
version, classifier, "pom", null);
@@ -123,7 +131,8 @@ public ModelSource resolveModel(
                     && 
coords.getVersionConstraint().getVersionRange().getUpperBoundary() == null) {
                 // Message below is checked for in the MNG-2199 core IT.
                 throw new ModelResolverException(
-                        "The requested " + (type != null ? type + " " : "") + 
"version range '" + version + "'"
+                        "The requested " + (modelType != null ? modelType + " 
" : "") + "version range '" + version
+                                + "'"
                                 + (location != null ? " (at " + location + ")" 
: "")
                                 + " does not specify an upper bound",
                         groupId,
@@ -132,18 +141,18 @@ public ModelSource resolveModel(
             }
             String newVersion = session.resolveHighestVersion(coords, 
repositories)
                     .orElseThrow(() -> new ModelResolverException(
-                            "No versions matched the requested " + (type != 
null ? type + " " : "") + "version range '"
-                                    + version + "'",
+                            "No versions matched the requested " + (modelType 
!= null ? modelType + " " : "")
+                                    + "version range '" + version + "'",
                             groupId,
                             artifactId,
                             version))
                     .asString();
-            if (!version.equals(newVersion)) {
-                resolvedVersion.accept(newVersion);
-            }
-
+            String resultVersion = version.equals(newVersion) ? null : 
newVersion;
             Path path = getPath(session, repositories, groupId, artifactId, 
newVersion, classifier);
-            return Sources.resolvedSource(path, groupId + ":" + artifactId + 
":" + newVersion);
+            return new ModelResolverResult(
+                    request,
+                    Sources.resolvedSource(path, groupId + ":" + artifactId + 
":" + newVersion),
+                    resultVersion);
         } catch (VersionRangeResolverException | ArtifactResolverException e) {
             throw new ModelResolverException(
                     e.getMessage() + " (remote repositories: "
@@ -154,6 +163,8 @@ public ModelSource resolveModel(
                     artifactId,
                     version,
                     e);
+        } finally {
+            RequestTraceHelper.exit(trace);
         }
     }
 


Reply via email to