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 2fb24de171be..d2566b6ffb3f 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,14 +21,21 @@ 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 java.util.stream.Collectors; +import java.util.stream.Stream; 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.Model; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginManagement; +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; @@ -64,6 +71,9 @@ public class DefaultPluginPrefixResolver implements PluginPrefixResolver { @Requirement private Logger logger; + @Requirement + private BuildPluginManager pluginManager; + @Requirement private RepositorySystem repositorySystem; @@ -73,6 +83,10 @@ public class DefaultPluginPrefixResolver implements PluginPrefixResolver { public PluginPrefixResult resolve(PluginPrefixRequest request) throws NoPluginFoundForPrefixException { logger.debug("Resolving plugin prefix " + request.getPrefix() + " from " + request.getPluginGroups()); + Model pom = request.getPom(); + Build build = pom != null ? pom.getBuild() : null; + PluginManagement management = build != null ? build.getPluginManagement() : 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 @@ -80,26 +94,26 @@ public PluginPrefixResult resolve(PluginPrefixRequest request) throws NoPluginFo // 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())); - } - } - } + LinkedHashMap> candidates = Stream.of(build, management) + .flatMap(container -> container != null ? container.getPlugins().stream() : Stream.empty()) + .filter(p -> !request.getPluginGroups().contains(p.getGroupId())) + .collect(Collectors.groupingBy( + Plugin::getGroupId, + LinkedHashMap::new, + Collectors.mapping(Plugin::getArtifactId, Collectors.toSet()))); request.getPluginGroups().forEach(g -> candidates.put(g, null)); PluginPrefixResult result = resolveFromRepository(request, candidates); + // If we haven't been able to resolve the plugin from the repository, + // as a last resort, we go through all declared plugins, load them + // one by one, and try to find a matching prefix. + if (result == null && build != null) { + result = resolveFromProject(request, build.getPlugins()); + if (result == null && management != null) { + result = resolveFromProject(request, management.getPlugins()); + } + } + if (result == null) { throw new NoPluginFoundForPrefixException( request.getPrefix(), @@ -115,6 +129,28 @@ public PluginPrefixResult resolve(PluginPrefixRequest request) throws NoPluginFo 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, LinkedHashMap> candidates) { RequestTrace trace = RequestTrace.newChild(null, request);