From 67f965829f41072fffe9805a739e646854b7c679 Mon Sep 17 00:00:00 2001 From: Tamas Cservenak Date: Thu, 28 Aug 2025 17:12:58 +0200 Subject: [PATCH] Simplify prefix resolution Simplify prefix resolution and drop use of BuildPluginManager (as descriptor will be re-resolved again later) and focus only on prefix to GA resolution, using a map of rules: * collect POM enlisted plugin groupId:artifactId pairs that come from non-settings-enlisted groupIDs (and allow only enlisted artifactIDs) * add settings enlisted plugin groupIds (keep their order) but "allow any" artifactId Using this map, figure out plugin GA from prefix using Maven metadata only. Fixes #11067 Backport of 2b7bb9c6fdb7b4bedc9b1c0581c70dc5b5a19671 --- .../internal/DefaultPluginPrefixResolver.java | 121 ++++++++---------- 1 file changed, 50 insertions(+), 71 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java index 38d17eba814f..2fb24de171be 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java @@ -21,15 +21,14 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.maven.artifact.repository.metadata.Metadata; import org.apache.maven.artifact.repository.metadata.io.MetadataReader; -import org.apache.maven.model.Build; -import org.apache.maven.model.Plugin; -import org.apache.maven.plugin.BuildPluginManager; -import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; import org.apache.maven.plugin.prefix.PluginPrefixRequest; import org.apache.maven.plugin.prefix.PluginPrefixResolver; @@ -65,9 +64,6 @@ public class DefaultPluginPrefixResolver implements PluginPrefixResolver { @Requirement private Logger logger; - @Requirement - private BuildPluginManager pluginManager; - @Requirement private RepositorySystem repositorySystem; @@ -77,76 +73,55 @@ public class DefaultPluginPrefixResolver implements PluginPrefixResolver { public PluginPrefixResult resolve(PluginPrefixRequest request) throws NoPluginFoundForPrefixException { logger.debug("Resolving plugin prefix " + request.getPrefix() + " from " + request.getPluginGroups()); - PluginPrefixResult result = resolveFromProject(request); - - if (result == null) { - result = resolveFromRepository(request); - - if (result == null) { - throw new NoPluginFoundForPrefixException( - request.getPrefix(), - request.getPluginGroups(), - request.getRepositorySession().getLocalRepository(), - request.getRepositories()); - } else if (logger.isDebugEnabled()) { - logger.debug("Resolved plugin prefix " + request.getPrefix() + " to " + result.getGroupId() + ":" - + result.getArtifactId() + " from repository " - + (result.getRepository() != null - ? result.getRepository().getId() - : "null")); + // map of groupId -> Set(artifactId) plugin candidates: + // if value is null, keys are coming from settings, and no artifactId filtering is applied + // if value is non-null: we allow only plugins that have enlisted artifactId only + // --- + // end game is: settings enlisted groupIds are obeying order and are "free for all" (artifactId) + // while POM enlisted plugins coming from non-enlisted settings groupIds (ie conflict of prefixes) + // will prevail/win. + LinkedHashMap> candidates = new LinkedHashMap<>(); + if (request.getPom() != null) { + if (request.getPom().getBuild() != null) { + request.getPom().getBuild().getPlugins().stream() + .filter(p -> !request.getPluginGroups().contains(p.getGroupId())) + .forEach(p -> candidates + .computeIfAbsent(p.getGroupId(), g -> new HashSet<>()) + .add(p.getArtifactId())); + if (request.getPom().getBuild().getPluginManagement() != null) { + request.getPom().getBuild().getPluginManagement().getPlugins().stream() + .filter(p -> !request.getPluginGroups().contains(p.getGroupId())) + .forEach(p -> candidates + .computeIfAbsent(p.getGroupId(), g -> new HashSet<>()) + .add(p.getArtifactId())); + } } - } else if (logger.isDebugEnabled()) { - logger.debug("Resolved plugin prefix " + request.getPrefix() + " to " + result.getGroupId() + ":" - + result.getArtifactId() + " from POM " + request.getPom()); } + request.getPluginGroups().forEach(g -> candidates.put(g, null)); + PluginPrefixResult result = resolveFromRepository(request, candidates); - return result; - } - - private PluginPrefixResult resolveFromProject(PluginPrefixRequest request) { - PluginPrefixResult result = null; - - if (request.getPom() != null && request.getPom().getBuild() != null) { - Build build = request.getPom().getBuild(); - - result = resolveFromProject(request, build.getPlugins()); - - if (result == null && build.getPluginManagement() != null) { - result = resolveFromProject(request, build.getPluginManagement().getPlugins()); - } + if (result == null) { + throw new NoPluginFoundForPrefixException( + request.getPrefix(), + new ArrayList<>(candidates.keySet()), + request.getRepositorySession().getLocalRepository(), + request.getRepositories()); + } else { + logger.debug("Resolved plugin prefix " + request.getPrefix() + " to " + result.getGroupId() + ":" + + result.getArtifactId() + " from repository " + + (result.getRepository() != null ? result.getRepository().getId() : "null")); } return result; } - private PluginPrefixResult resolveFromProject(PluginPrefixRequest request, List plugins) { - for (Plugin plugin : plugins) { - try { - PluginDescriptor pluginDescriptor = - pluginManager.loadPlugin(plugin, request.getRepositories(), request.getRepositorySession()); - - if (request.getPrefix().equals(pluginDescriptor.getGoalPrefix())) { - return new DefaultPluginPrefixResult(plugin); - } - } catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.warn( - "Failed to retrieve plugin descriptor for " + plugin.getId() + ": " + e.getMessage(), e); - } else { - logger.warn("Failed to retrieve plugin descriptor for " + plugin.getId() + ": " + e.getMessage()); - } - } - } - - return null; - } - - private PluginPrefixResult resolveFromRepository(PluginPrefixRequest request) { + private PluginPrefixResult resolveFromRepository( + PluginPrefixRequest request, LinkedHashMap> candidates) { RequestTrace trace = RequestTrace.newChild(null, request); List requests = new ArrayList<>(); - for (String pluginGroup : request.getPluginGroups()) { + for (String pluginGroup : candidates.keySet()) { org.eclipse.aether.metadata.Metadata metadata = new DefaultMetadata(pluginGroup, "maven-metadata.xml", DefaultMetadata.Nature.RELEASE_OR_SNAPSHOT); @@ -162,7 +137,7 @@ private PluginPrefixResult resolveFromRepository(PluginPrefixRequest request) { List results = repositorySystem.resolveMetadata(request.getRepositorySession(), requests); requests.clear(); - PluginPrefixResult result = processResults(request, trace, results, requests); + PluginPrefixResult result = processResults(request, trace, results, requests, candidates); if (result != null) { return result; @@ -176,7 +151,7 @@ private PluginPrefixResult resolveFromRepository(PluginPrefixRequest request) { results = repositorySystem.resolveMetadata(session, requests); - return processResults(request, trace, results, null); + return processResults(request, trace, results, null, candidates); } return null; @@ -186,7 +161,8 @@ private PluginPrefixResult processResults( PluginPrefixRequest request, RequestTrace trace, List results, - List requests) { + List requests, + LinkedHashMap> candidates) { for (MetadataResult res : results) { org.eclipse.aether.metadata.Metadata metadata = res.getMetadata(); @@ -197,7 +173,7 @@ private PluginPrefixResult processResults( } PluginPrefixResult result = - resolveFromRepository(request, trace, metadata.getGroupId(), metadata, repository); + resolveFromRepository(request, trace, metadata.getGroupId(), metadata, repository, candidates); if (result != null) { return result; @@ -217,7 +193,8 @@ private PluginPrefixResult resolveFromRepository( RequestTrace trace, String pluginGroup, org.eclipse.aether.metadata.Metadata metadata, - ArtifactRepository repository) { + ArtifactRepository repository, + LinkedHashMap> candidates) { if (metadata != null && metadata.getFile() != null && metadata.getFile().isFile()) { try { Map options = Collections.singletonMap(MetadataReader.IS_STRICT, Boolean.FALSE); @@ -228,7 +205,9 @@ private PluginPrefixResult resolveFromRepository( if (plugins != null) { for (org.apache.maven.artifact.repository.metadata.Plugin plugin : plugins) { - if (request.getPrefix().equals(plugin.getPrefix())) { + if (request.getPrefix().equals(plugin.getPrefix()) + && (candidates.get(pluginGroup) == null + || candidates.get(pluginGroup).contains(plugin.getArtifactId()))) { return new DefaultPluginPrefixResult(pluginGroup, plugin.getArtifactId(), repository); } }