From 4cdcd841f4d9569380662605f2c519e6ff6a8b3f Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Thu, 16 Jan 2025 19:24:31 +0100 Subject: [PATCH] Implement traces (wip) --- .../java/org/apache/maven/api/Session.java | 5 ++++ .../maven/api/services/BaseRequest.java | 6 ++++- .../api/services/ModelBuilderRequest.java | 11 +++++++- .../maven/api/services/RequestTrace.java | 11 +++++++- .../internal/impl/DefaultProjectBuilder.java | 2 ++ .../maven/internal/impl/AbstractSession.java | 17 ++++++++++++ .../impl/DefaultArtifactResolver.java | 5 +++- .../impl/DefaultDependencyResolver.java | 7 ++++- .../impl/DefaultVersionRangeResolver.java | 15 ++++++----- .../internal/impl/DefaultVersionResolver.java | 10 ++++--- .../impl/model/DefaultModelBuilder.java | 3 +++ .../DefaultArtifactDescriptorReader.java | 1 + .../impl/resolver/RequestTraceHelper.java | 27 +++++++++++++++++++ 13 files changed, 105 insertions(+), 15 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 39ae21a0cc15..c862dfba00e7 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 @@ -32,6 +32,7 @@ import org.apache.maven.api.model.Repository; import org.apache.maven.api.services.ArtifactCoordinatesFactory; import org.apache.maven.api.services.DependencyCoordinatesFactory; +import org.apache.maven.api.services.RequestTrace; import org.apache.maven.api.services.VersionResolverException; import org.apache.maven.api.settings.Settings; @@ -843,4 +844,8 @@ Optional resolveHighestVersion(@Nonnull ArtifactCoordinates artifact, L */ @Nonnull PathScope requirePathScope(@Nonnull String id); + + void setCurrentTrace(@Nonnull RequestTrace trace); + + RequestTrace getCurrentTrace(); } diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/BaseRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/BaseRequest.java index 2b4a12a19929..6bf2c31b223b 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/BaseRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/BaseRequest.java @@ -36,8 +36,12 @@ abstract class BaseRequest implements Request { private final RequestTrace trace; protected BaseRequest(@Nonnull S session) { + this(session, null); + } + + protected BaseRequest(@Nonnull S session, RequestTrace trace) { this.session = requireNonNull(session, "session cannot be null"); - this.trace = null; + this.trace = trace; } @Nonnull diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelBuilderRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelBuilderRequest.java index 88f897309a2b..5e7442939936 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelBuilderRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelBuilderRequest.java @@ -174,6 +174,7 @@ static ModelBuilderRequestBuilder builder(ModelBuilderRequest request) { @NotThreadSafe class ModelBuilderRequestBuilder { Session session; + RequestTrace trace; RequestType requestType; boolean locationTracking; boolean recursive; @@ -191,6 +192,7 @@ class ModelBuilderRequestBuilder { ModelBuilderRequestBuilder(ModelBuilderRequest request) { this.session = request.getSession(); + this.trace = request.getTrace(); this.requestType = request.getRequestType(); this.locationTracking = request.isLocationTracking(); this.recursive = request.isRecursive(); @@ -210,6 +212,11 @@ public ModelBuilderRequestBuilder session(Session session) { return this; } + public ModelBuilderRequestBuilder trace(RequestTrace trace) { + this.trace = trace; + return this; + } + public ModelBuilderRequestBuilder requestType(RequestType requestType) { this.requestType = requestType; return this; @@ -273,6 +280,7 @@ public ModelBuilderRequestBuilder lifecycleBindingsInjector(ModelTransformer lif public ModelBuilderRequest build() { return new DefaultModelBuilderRequest( session, + trace, requestType, locationTracking, recursive, @@ -304,6 +312,7 @@ private static class DefaultModelBuilderRequest extends BaseRequest imp @SuppressWarnings("checkstyle:ParameterNumber") DefaultModelBuilderRequest( @Nonnull Session session, + @Nullable RequestTrace trace, @Nonnull RequestType requestType, boolean locationTracking, boolean recursive, @@ -316,7 +325,7 @@ private static class DefaultModelBuilderRequest extends BaseRequest imp RepositoryMerging repositoryMerging, List repositories, ModelTransformer lifecycleBindingsInjector) { - super(session); + super(session, trace); this.requestType = requireNonNull(requestType, "requestType cannot be null"); this.locationTracking = locationTracking; this.recursive = recursive; diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/RequestTrace.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/RequestTrace.java index 16e22779dfeb..6dafc3aeaf57 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/RequestTrace.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/RequestTrace.java @@ -50,4 +50,13 @@ * object being processed or any application-specific state information. May be null if no * additional data is needed. */ -public record RequestTrace(@Nullable String context, @Nullable RequestTrace parent, @Nullable Object data) {} +public record RequestTrace(@Nullable String context, @Nullable RequestTrace parent, @Nullable Object data) { + + public static final String CONTEXT_PLUGIN = "plugin"; + public static final String CONTEXT_PROJECT = "project"; + public static final String CONTEXT_BOOTSTRAP = "bootstrap"; + + public RequestTrace(RequestTrace parent, Object data) { + this(parent != null ? parent.context() : null, parent, data); + } +} 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 fe8509f15a5c..540557705997 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 @@ -41,6 +41,7 @@ import org.apache.maven.api.services.ProjectBuilderResult; import org.apache.maven.api.services.Source; import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.internal.impl.resolver.RequestTraceHelper; import org.apache.maven.model.building.ModelProblem; import org.apache.maven.model.building.ModelSource2; import org.apache.maven.project.DefaultProjectBuildingRequest; @@ -65,6 +66,7 @@ public DefaultProjectBuilder(org.apache.maven.project.ProjectBuilder builder) { public ProjectBuilderResult build(ProjectBuilderRequest request) throws ProjectBuilderException, IllegalArgumentException { InternalMavenSession session = InternalMavenSession.from(request.getSession()); + RequestTraceHelper.enter(request.getSession(), request); try { List repositories = session.toArtifactRepositories( request.getRepositories() != null ? request.getRepositories() : session.getRemoteRepositories()); diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/AbstractSession.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/AbstractSession.java index 75d32bc04be8..e1187517c97c 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/AbstractSession.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/AbstractSession.java @@ -84,6 +84,7 @@ 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.RequestTrace; import org.apache.maven.api.services.TypeRegistry; import org.apache.maven.api.services.VersionParser; import org.apache.maven.api.services.VersionRangeResolver; @@ -900,4 +901,20 @@ public DependencyScope requireDependencyScope(String id) { public PathScope requirePathScope(String id) { return getService(PathScopeRegistry.class).require(id); } + + @Override + public void setCurrentTrace(RequestTrace trace) { + getTraceHolder().set(trace); + } + + @Override + public RequestTrace getCurrentTrace() { + return getTraceHolder().get(); + } + + @SuppressWarnings("unchecked") + private ThreadLocal getTraceHolder() { + org.eclipse.aether.SessionData data = session.getData(); + return (ThreadLocal) data.computeIfAbsent(RequestTrace.class, ThreadLocal::new); + } } diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultArtifactResolver.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultArtifactResolver.java index 43fc7538ad73..f87f3820cc9a 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultArtifactResolver.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultArtifactResolver.java @@ -35,6 +35,7 @@ import org.apache.maven.api.services.ArtifactResolverException; import org.apache.maven.api.services.ArtifactResolverRequest; import org.apache.maven.api.services.ArtifactResolverResult; +import org.apache.maven.internal.impl.resolver.RequestTraceHelper; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.resolution.ArtifactRequest; import org.eclipse.aether.resolution.ArtifactResolutionException; @@ -52,6 +53,7 @@ public ArtifactResolverResult resolve(ArtifactResolverRequest request) nonNull(request, "request"); InternalSession session = InternalSession.from(request.getSession()); try { + RequestTraceHelper.ResolverTrace trace = RequestTraceHelper.enter(session, request); Map paths = new HashMap<>(); ArtifactManager artifactManager = session.getService(ArtifactManager.class); List repositories = session.toRepositories( @@ -68,7 +70,8 @@ public ArtifactResolverResult resolve(ArtifactResolverRequest request) DownloadedArtifact resolved = session.getArtifact(DownloadedArtifact.class, aetherArtifact); paths.put(resolved, path); } else { - requests.add(new ArtifactRequest(aetherArtifact, repositories, null)); + requests.add( + new ArtifactRequest(aetherArtifact, repositories, trace.context()).setTrace(trace.trace())); } } if (!requests.isEmpty()) { diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java index ae393b86fc18..aa95854a019c 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java @@ -50,6 +50,7 @@ import org.apache.maven.api.services.DependencyResolverRequest; import org.apache.maven.api.services.DependencyResolverResult; import org.apache.maven.api.services.ProjectManager; +import org.apache.maven.internal.impl.resolver.RequestTraceHelper; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.collection.CollectRequest; @@ -75,6 +76,7 @@ public DependencyResolverResult collect(@Nonnull DependencyResolverRequest reque throws DependencyResolverException, IllegalArgumentException { nonNull(request, "request"); InternalSession session = InternalSession.from(request.getSession()); + RequestTraceHelper.ResolverTrace trace = RequestTraceHelper.enter(session, request); Artifact rootArtifact; DependencyCoordinates root; @@ -110,7 +112,9 @@ public DependencyResolverResult collect(@Nonnull DependencyResolverRequest reque .setRoot(root != null ? session.toDependency(root, false) : null) .setDependencies(session.toDependencies(dependencies, false)) .setManagedDependencies(session.toDependencies(managedDependencies, true)) - .setRepositories(session.toRepositories(remoteRepositories)); + .setRepositories(session.toRepositories(remoteRepositories)) + .setRequestContext(trace.context()) + .setTrace(trace.trace()); collectRequest.setResolutionScope(resolutionScope); RepositorySystemSession systemSession = session.getSession(); @@ -165,6 +169,7 @@ public DependencyResolverResult resolve(DependencyResolverRequest request) throws DependencyResolverException, DependencyResolverException, ArtifactResolverException { InternalSession session = InternalSession.from(nonNull(request, "request").getSession()); + RequestTraceHelper.enter(session, request); DependencyResolverResult result; DependencyResolverResult collectorResult = collect(request); List repositories = request.getRepositories() != null diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultVersionRangeResolver.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultVersionRangeResolver.java index 0394e1ee2476..f57b191397a7 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultVersionRangeResolver.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultVersionRangeResolver.java @@ -32,6 +32,7 @@ import org.apache.maven.api.services.VersionRangeResolverException; import org.apache.maven.api.services.VersionRangeResolverRequest; import org.apache.maven.api.services.VersionRangeResolverResult; +import org.apache.maven.internal.impl.resolver.RequestTraceHelper; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.repository.ArtifactRepository; import org.eclipse.aether.resolution.VersionRangeRequest; @@ -59,15 +60,17 @@ public VersionRangeResolverResult resolve(VersionRangeResolverRequest request) InternalSession session = InternalSession.from(request.getSession()); try { + RequestTraceHelper.ResolverTrace trace = RequestTraceHelper.enter(session, request); VersionRangeResult res = repositorySystem.resolveVersionRange( session.getSession(), new VersionRangeRequest( - session.toArtifact(request.getArtifactCoordinates()), - session.toRepositories( - request.getRepositories() != null - ? request.getRepositories() - : session.getRemoteRepositories()), - null)); + session.toArtifact(request.getArtifactCoordinates()), + session.toRepositories( + request.getRepositories() != null + ? request.getRepositories() + : session.getRemoteRepositories()), + trace.context()) + .setTrace(trace.trace())); Map repos = res.getVersions().stream() .filter(v -> res.getRepository(v) != null) diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultVersionResolver.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultVersionResolver.java index 27c8fe09f574..6ce6db6672cd 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultVersionResolver.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/DefaultVersionResolver.java @@ -30,6 +30,7 @@ import org.apache.maven.api.services.VersionResolverException; import org.apache.maven.api.services.VersionResolverRequest; import org.apache.maven.api.services.VersionResolverResult; +import org.apache.maven.internal.impl.resolver.RequestTraceHelper; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.resolution.VersionRequest; import org.eclipse.aether.resolution.VersionResolutionException; @@ -54,15 +55,16 @@ public VersionResolverResult resolve(VersionResolverRequest request) throws Vers InternalSession session = InternalSession.from(request.getSession()); try { - VersionResult res = repositorySystem.resolveVersion( - session.getSession(), - new VersionRequest( + RequestTraceHelper.ResolverTrace trace = RequestTraceHelper.enter(session, request); + VersionRequest req = new VersionRequest( session.toArtifact(request.getArtifactCoordinates()), session.toRepositories( request.getRepositories() != null ? request.getRepositories() : session.getRemoteRepositories()), - null)); + trace.context()) + .setTrace(trace.trace()); + VersionResult res = repositorySystem.resolveVersion(session.getSession(), req); return new VersionResolverResult() { @Override diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/model/DefaultModelBuilder.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/model/DefaultModelBuilder.java index 2d589f7f9ec2..eecc0a6e7cb6 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/model/DefaultModelBuilder.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/model/DefaultModelBuilder.java @@ -109,6 +109,7 @@ import org.apache.maven.api.services.xml.XmlReaderRequest; import org.apache.maven.api.spi.ModelParserException; import org.apache.maven.api.spi.ModelTransformer; +import org.apache.maven.internal.impl.resolver.RequestTraceHelper; import org.apache.maven.internal.impl.util.PhasingExecutor; import org.apache.maven.model.v4.MavenTransformer; import org.slf4j.Logger; @@ -217,6 +218,7 @@ protected class ModelBuilderSessionImpl implements ModelBuilderSession { */ @Override public ModelBuilderResult build(ModelBuilderRequest request) throws ModelBuilderException { + RequestTraceHelper.enter(request.getSession(), request); // Create or derive a session based on the request ModelBuilderSessionState session; if (mainSession == null) { @@ -1814,6 +1816,7 @@ private static List getSubprojects(Model activated) { @Override public Model buildRawModel(ModelBuilderRequest request) throws ModelBuilderException { + RequestTraceHelper.enter(request.getSession(), request); ModelBuilderSessionState build = new ModelBuilderSessionState(request); Model model = build.readRawModel(); if (build.hasErrors()) { diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/DefaultArtifactDescriptorReader.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/DefaultArtifactDescriptorReader.java index e046d1b14f39..6554eae20bab 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/DefaultArtifactDescriptorReader.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/DefaultArtifactDescriptorReader.java @@ -195,6 +195,7 @@ private Model loadPom( pomArtifact.getGroupId() + ":" + pomArtifact.getArtifactId() + ":" + pomArtifact.getVersion(); ModelBuilderRequest modelRequest = ModelBuilderRequest.builder() .session(iSession) + .trace(RequestTraceHelper.toMaven(request.getRequestContext(), trace)) .requestType(ModelBuilderRequest.RequestType.CONSUMER_DEPENDENCY) .source(ModelSource.fromPath(pomArtifact.getPath(), gav)) // This merge is on purpose because otherwise user properties would override model diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/RequestTraceHelper.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/RequestTraceHelper.java index 25223a9c3a97..b157a9959fb2 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/RequestTraceHelper.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/RequestTraceHelper.java @@ -20,6 +20,7 @@ import java.util.stream.Collectors; +import org.apache.maven.api.Session; import org.eclipse.aether.RequestTrace; import org.eclipse.aether.collection.CollectRequest; import org.eclipse.aether.collection.CollectStepData; @@ -32,6 +33,32 @@ */ public final class RequestTraceHelper { + public record ResolverTrace(String context, RequestTrace trace) {} + + public static ResolverTrace enter(Session session, Object data) { + org.apache.maven.api.services.RequestTrace trace = + new org.apache.maven.api.services.RequestTrace(session.getCurrentTrace(), data); + session.setCurrentTrace(trace); + return new ResolverTrace(trace.context(), toResolver(trace)); + } + + public static org.apache.maven.api.services.RequestTrace toMaven(String context, RequestTrace trace) { + if (trace != null) { + return new org.apache.maven.api.services.RequestTrace( + context, toMaven(context, trace.getParent()), trace.getData()); + } else { + return null; + } + } + + public static RequestTrace toResolver(org.apache.maven.api.services.RequestTrace trace) { + if (trace != null) { + return RequestTrace.newChild(toResolver(trace.parent()), trace.data()); + } else { + return null; + } + } + /** * Method that creates some informational string based on passed in {@link RequestTrace}. The contents of request * trace can literally be anything, but this class tries to cover "most common" cases that are happening in Maven.