diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginValidationManager.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginValidationManager.java
new file mode 100644
index 0000000000..aaf0f29c48
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginValidationManager.java
@@ -0,0 +1,55 @@
+/*
+ * 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.plugin;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+
+/**
+ * Component collecting plugin validation issues and reporting them.
+ *
+ * @since 3.9.2
+ */
+public interface PluginValidationManager {
+ /**
+ * Reports plugin issues applicable to the plugin as a whole.
+ *
+ * This method should be used in "early" phase of plugin execution, possibly even when plugin or mojo descriptor
+ * does not exist yet. In turn, this method will not record extra information like plugin occurrence or declaration
+ * location as those are not yet available.
+ */
+ void reportPluginValidationIssue(RepositorySystemSession session, Artifact pluginArtifact, String issue);
+
+ /**
+ * Reports plugin issues applicable to the plugin as a whole.
+ *
+ * This method will record extra information as well, like plugin occurrence or declaration location.
+ */
+ void reportPluginValidationIssue(MavenSession mavenSession, MojoDescriptor mojoDescriptor, String issue);
+
+ /**
+ * Reports plugin Mojo issues applicable to the Mojo itself.
+ *
+ * This method will record extra information as well, like plugin occurrence or declaration location.
+ */
+ void reportPluginMojoValidationIssue(
+ MavenSession mavenSession, MojoDescriptor mojoDescriptor, Class> mojoClass, String issue);
+}
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginDependenciesValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginDependenciesValidator.java
new file mode 100644
index 0000000000..6f75c0d337
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginDependenciesValidator.java
@@ -0,0 +1,55 @@
+/*
+ * 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.plugin.internal;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.PluginValidationManager;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Service responsible for validating plugin dependencies.
+ *
+ * @since 3.9.2
+ */
+abstract class AbstractMavenPluginDependenciesValidator implements MavenPluginDependenciesValidator {
+
+ protected final List expectedProvidedScopeExclusions = Arrays.asList(
+ "org.apache.maven:maven-archiver", "org.apache.maven:maven-jxr", "org.apache.maven:plexus-utils");
+
+ protected final PluginValidationManager pluginValidationManager;
+
+ protected AbstractMavenPluginDependenciesValidator(PluginValidationManager pluginValidationManager) {
+ this.pluginValidationManager = requireNonNull(pluginValidationManager);
+ }
+
+ @Override
+ public void validate(MavenSession mavenSession, MojoDescriptor mojoDescriptor) {
+ if (mojoDescriptor.getPluginDescriptor() != null
+ && mojoDescriptor.getPluginDescriptor().getDependencies() != null) {
+ doValidate(mavenSession, mojoDescriptor);
+ }
+ }
+
+ protected abstract void doValidate(MavenSession mavenSession, MojoDescriptor mojoDescriptor);
+}
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginDescriptorSourcedParametersValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginDescriptorSourcedParametersValidator.java
index 94ca557812..76a0e16a4d 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginDescriptorSourcedParametersValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginDescriptorSourcedParametersValidator.java
@@ -21,6 +21,8 @@
import java.util.Arrays;
import java.util.List;
+import org.apache.maven.plugin.PluginValidationManager;
+
/**
* Common implementations for plugin parameters configuration validation that relies on Mojo descriptor (leaves out
* core parameters by default).
@@ -48,6 +50,10 @@ abstract class AbstractMavenPluginDescriptorSourcedParametersValidator extends A
private static final List IGNORED_PROPERTY_PREFIX =
Arrays.asList("mojo.", "pom.", "plugin.", "project.", "session.", "settings.");
+ protected AbstractMavenPluginDescriptorSourcedParametersValidator(PluginValidationManager pluginValidationManager) {
+ super(pluginValidationManager);
+ }
+
@Override
protected boolean isIgnoredProperty(String strValue) {
if (!strValue.startsWith("${")) {
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginParametersValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginParametersValidator.java
index 809a75dfc2..c5eeb72c75 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginParametersValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginParametersValidator.java
@@ -18,15 +18,15 @@
*/
package org.apache.maven.plugin.internal;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.PluginValidationManager;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
-import org.apache.maven.shared.utils.logging.MessageBuilder;
-import org.apache.maven.shared.utils.logging.MessageUtils;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.configuration.PlexusConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import static java.util.Objects.requireNonNull;
/**
* Common implementations for plugin parameters configuration validation.
@@ -35,7 +35,11 @@
*/
abstract class AbstractMavenPluginParametersValidator implements MavenPluginConfigurationValidator {
- protected final Logger logger = LoggerFactory.getLogger(getClass());
+ protected final PluginValidationManager pluginValidationManager;
+
+ protected AbstractMavenPluginParametersValidator(PluginValidationManager pluginValidationManager) {
+ this.pluginValidationManager = requireNonNull(pluginValidationManager);
+ }
protected boolean isValueSet(PlexusConfiguration config, ExpressionEvaluator expressionEvaluator) {
if (config == null) {
@@ -73,18 +77,18 @@ protected boolean isValueSet(PlexusConfiguration config, ExpressionEvaluator exp
@Override
public final void validate(
+ MavenSession mavenSession,
MojoDescriptor mojoDescriptor,
+ Class> mojoClass,
PlexusConfiguration pomConfiguration,
ExpressionEvaluator expressionEvaluator) {
- if (!logger.isWarnEnabled()) {
- return;
- }
-
- doValidate(mojoDescriptor, pomConfiguration, expressionEvaluator);
+ doValidate(mavenSession, mojoDescriptor, mojoClass, pomConfiguration, expressionEvaluator);
}
protected abstract void doValidate(
+ MavenSession mavenSession,
MojoDescriptor mojoDescriptor,
+ Class> mojoClass,
PlexusConfiguration pomConfiguration,
ExpressionEvaluator expressionEvaluator);
@@ -94,19 +98,19 @@ protected boolean isIgnoredProperty(String strValue) {
protected abstract String getParameterLogReason(Parameter parameter);
- protected void logParameter(Parameter parameter) {
- MessageBuilder messageBuilder = MessageUtils.buffer()
- .warning("Parameter '")
- .warning(parameter.getName())
- .warning('\'');
+ protected String formatParameter(Parameter parameter) {
+ StringBuilder stringBuilder = new StringBuilder()
+ .append("Parameter '")
+ .append(parameter.getName())
+ .append('\'');
if (parameter.getExpression() != null) {
String userProperty = parameter.getExpression().replace("${", "'").replace('}', '\'');
- messageBuilder.warning(" (user property ").warning(userProperty).warning(")");
+ stringBuilder.append(" (user property ").append(userProperty).append(")");
}
- messageBuilder.warning(" ").warning(getParameterLogReason(parameter));
+ stringBuilder.append(" ").append(getParameterLogReason(parameter));
- logger.warn(messageBuilder.toString());
+ return stringBuilder.toString();
}
}
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
index 1e29fec5b3..47bb66dcf3 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
@@ -71,6 +71,7 @@
import org.apache.maven.plugin.PluginParameterExpressionEvaluatorV4;
import org.apache.maven.plugin.PluginRealmCache;
import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.PluginValidationManager;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
@@ -99,6 +100,7 @@
import org.codehaus.plexus.configuration.DefaultPlexusConfiguration;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.PlexusConfigurationException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
import org.eclipse.aether.RepositorySystemSession;
@@ -146,8 +148,9 @@ public class DefaultMavenPluginManager implements MavenPluginManager {
private PluginArtifactsCache pluginArtifactsCache;
private MavenPluginValidator pluginValidator;
private List configurationValidators;
+ private List dependenciesValidators;
+ private PluginValidationManager pluginValidationManager;
private List prerequisitesCheckers;
-
private final ExtensionDescriptorBuilder extensionDescriptorBuilder = new ExtensionDescriptorBuilder();
private final PluginDescriptorBuilder builder = new PluginDescriptorBuilder();
@@ -165,6 +168,8 @@ public DefaultMavenPluginManager(
PluginArtifactsCache pluginArtifactsCache,
MavenPluginValidator pluginValidator,
List configurationValidators,
+ List dependencyValidators,
+ PluginValidationManager pluginValidationManager,
List prerequisitesCheckers) {
this.container = container;
this.classRealmManager = classRealmManager;
@@ -177,6 +182,8 @@ public DefaultMavenPluginManager(
this.pluginArtifactsCache = pluginArtifactsCache;
this.pluginValidator = pluginValidator;
this.configurationValidators = configurationValidators;
+ this.dependenciesValidators = dependencyValidators;
+ this.pluginValidationManager = pluginValidationManager;
this.prerequisitesCheckers = prerequisitesCheckers;
}
@@ -559,6 +566,18 @@ public T getConfiguredMojo(Class mojoInterface, MavenSession session, Moj
((Mojo) mojo).setLog(new MojoLogWrapper(mojoLogger));
}
+ if (mojo instanceof Contextualizable) {
+ pluginValidationManager.reportPluginMojoValidationIssue(
+ session,
+ mojoDescriptor,
+ mojo.getClass(),
+ "Implements `Contextualizable` interface from Plexus Container, which is EOL.");
+ }
+
+ for (MavenPluginDependenciesValidator validator : dependenciesValidators) {
+ validator.validate(session, mojoDescriptor);
+ }
+
XmlNode dom = mojoExecution.getConfiguration() != null
? mojoExecution.getConfiguration().getDom()
: null;
@@ -582,7 +601,7 @@ public T getConfiguredMojo(Class mojoInterface, MavenSession session, Moj
}
for (MavenPluginConfigurationValidator validator : configurationValidators) {
- validator.validate(mojoDescriptor, pomConfiguration, expressionEvaluator);
+ validator.validate(session, mojoDescriptor, mojo.getClass(), pomConfiguration, expressionEvaluator);
}
populateMojoExecutionFields(
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
index 4b1120838d..35fc123f7c 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
@@ -32,6 +32,7 @@
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.PluginValidationManager;
import org.codehaus.plexus.util.StringUtils;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
@@ -77,9 +78,13 @@ public class DefaultPluginDependenciesResolver implements PluginDependenciesReso
private final RepositorySystem repoSystem;
+ private final PluginValidationManager pluginValidationManager;
+
@Inject
- public DefaultPluginDependenciesResolver(RepositorySystem repoSystem) {
+ public DefaultPluginDependenciesResolver(
+ RepositorySystem repoSystem, PluginValidationManager pluginValidationManager) {
this.repoSystem = repoSystem;
+ this.pluginValidationManager = pluginValidationManager;
}
private Artifact toArtifact(Plugin plugin, RepositorySystemSession session) {
@@ -107,6 +112,19 @@ public Artifact resolve(Plugin plugin, List repositories, Repo
request.setTrace(trace);
ArtifactDescriptorResult result = repoSystem.readArtifactDescriptor(pluginSession, request);
+ if (result.getDependencies() != null) {
+ for (org.eclipse.aether.graph.Dependency dependency : result.getDependencies()) {
+ if ("org.apache.maven".equals(dependency.getArtifact().getGroupId())
+ && "maven-compat".equals(dependency.getArtifact().getArtifactId())
+ && !JavaScopes.TEST.equals(dependency.getScope())) {
+ pluginValidationManager.reportPluginValidationIssue(
+ session,
+ pluginArtifact,
+ "Plugin depends on the deprecated Maven 2.x compatibility layer, which may not be supported in Maven 4.x");
+ }
+ }
+ }
+
pluginArtifact = result.getArtifact();
if (logger.isWarnEnabled()) {
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginValidationManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginValidationManager.java
new file mode 100644
index 0000000000..57ce4ebab3
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginValidationManager.java
@@ -0,0 +1,270 @@
+/*
+ * 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.plugin.internal;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.maven.AbstractMavenLifecycleParticipant;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.InputLocation;
+import org.apache.maven.plugin.PluginValidationManager;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.util.ConfigUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+@Named
+public final class DefaultPluginValidationManager extends AbstractMavenLifecycleParticipant
+ implements PluginValidationManager {
+
+ private static final String ISSUES_KEY = DefaultPluginValidationManager.class.getName() + ".issues";
+
+ private static final String MAVEN_PLUGIN_VALIDATION_KEY = "maven.plugin.validation";
+
+ private enum ValidationLevel {
+ DISABLED,
+ ENABLED,
+ VERBOSE
+ }
+
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+
+ @Override
+ public void afterSessionEnd(MavenSession session) {
+ reportSessionCollectedValidationIssues(session);
+ }
+
+ private ValidationLevel validationLevel(RepositorySystemSession session) {
+ String level = ConfigUtils.getString(session, null, MAVEN_PLUGIN_VALIDATION_KEY);
+ if (level == null || level.isEmpty()) {
+ return ValidationLevel.ENABLED;
+ }
+ try {
+ return ValidationLevel.valueOf(level.toUpperCase(Locale.ENGLISH));
+ } catch (IllegalArgumentException e) {
+ logger.warn(
+ "Invalid value specified for property {}: '{}'. Supported values are (case insensitive): {}",
+ MAVEN_PLUGIN_VALIDATION_KEY,
+ level,
+ Arrays.toString(ValidationLevel.values()));
+ return ValidationLevel.ENABLED;
+ }
+ }
+
+ private String pluginKey(String groupId, String artifactId, String version) {
+ return groupId + ":" + artifactId + ":" + version;
+ }
+
+ private String pluginKey(MojoDescriptor mojoDescriptor) {
+ PluginDescriptor pd = mojoDescriptor.getPluginDescriptor();
+ return pluginKey(pd.getGroupId(), pd.getArtifactId(), pd.getVersion());
+ }
+
+ private String pluginKey(Artifact pluginArtifact) {
+ return pluginKey(pluginArtifact.getGroupId(), pluginArtifact.getArtifactId(), pluginArtifact.getVersion());
+ }
+
+ @Override
+ public void reportPluginValidationIssue(RepositorySystemSession session, Artifact pluginArtifact, String issue) {
+ String pluginKey = pluginKey(pluginArtifact);
+ PluginValidationIssues pluginIssues =
+ pluginIssues(session).computeIfAbsent(pluginKey, k -> new PluginValidationIssues());
+ pluginIssues.reportPluginIssue(null, null, issue);
+ }
+
+ @Override
+ public void reportPluginValidationIssue(MavenSession mavenSession, MojoDescriptor mojoDescriptor, String issue) {
+ String pluginKey = pluginKey(mojoDescriptor);
+ PluginValidationIssues pluginIssues = pluginIssues(mavenSession.getRepositorySession())
+ .computeIfAbsent(pluginKey, k -> new PluginValidationIssues());
+ pluginIssues.reportPluginIssue(
+ pluginDeclaration(mavenSession, mojoDescriptor), pluginOccurrence(mavenSession), issue);
+ }
+
+ @Override
+ public void reportPluginMojoValidationIssue(
+ MavenSession mavenSession, MojoDescriptor mojoDescriptor, Class> mojoClass, String issue) {
+ String pluginKey = pluginKey(mojoDescriptor);
+ PluginValidationIssues pluginIssues = pluginIssues(mavenSession.getRepositorySession())
+ .computeIfAbsent(pluginKey, k -> new PluginValidationIssues());
+ pluginIssues.reportPluginMojoIssue(
+ pluginDeclaration(mavenSession, mojoDescriptor),
+ pluginOccurrence(mavenSession),
+ mojoInfo(mojoDescriptor, mojoClass),
+ issue);
+ }
+
+ private void reportSessionCollectedValidationIssues(MavenSession mavenSession) {
+ ValidationLevel validationLevel = validationLevel(mavenSession.getRepositorySession());
+ ConcurrentHashMap issuesMap = pluginIssues(mavenSession.getRepositorySession());
+ if (!issuesMap.isEmpty()) {
+
+ logger.warn("");
+ logger.warn("Plugin validation issues were detected in {} plugin(s)", issuesMap.size());
+ logger.warn("");
+ if (validationLevel == ValidationLevel.DISABLED || !logger.isWarnEnabled()) {
+ return;
+ }
+
+ for (Map.Entry entry : issuesMap.entrySet()) {
+ logger.warn("Plugin {}", entry.getKey());
+ PluginValidationIssues issues = entry.getValue();
+ if (validationLevel == ValidationLevel.VERBOSE && !issues.pluginDeclarations.isEmpty()) {
+ logger.warn(" Declared at location(s):");
+ for (String pluginDeclaration : issues.pluginDeclarations) {
+ logger.warn(" * {}", pluginDeclaration);
+ }
+ }
+ if (validationLevel == ValidationLevel.VERBOSE && !issues.pluginOccurrences.isEmpty()) {
+ logger.warn(" Used in module(s):");
+ for (String pluginOccurrence : issues.pluginOccurrences) {
+ logger.warn(" * {}", pluginOccurrence);
+ }
+ }
+ if (!issues.pluginIssues.isEmpty()) {
+ logger.warn(" Plugin issue(s):");
+ for (String pluginIssue : issues.pluginIssues) {
+ logger.warn(" * {}", pluginIssue);
+ }
+ }
+ if (!issues.mojoIssues.isEmpty()) {
+ logger.warn(" Mojo issue(s):");
+ for (String mojoInfo : issues.mojoIssues.keySet()) {
+ logger.warn(" * Mojo {}", mojoInfo);
+ for (String mojoIssue : issues.mojoIssues.get(mojoInfo)) {
+ logger.warn(" - {}", mojoIssue);
+ }
+ }
+ }
+ logger.warn("");
+ }
+ logger.warn("");
+ logger.warn(
+ "To fix these issues, please upgrade above listed plugins, or, notify their maintainers about reported issues.");
+ logger.warn("");
+ logger.warn(
+ "For more or less details, use 'maven.plugin.validation' property with one of the values (case insensitive): {}",
+ Arrays.toString(ValidationLevel.values()));
+ logger.warn("");
+ }
+ }
+
+ private String pluginDeclaration(MavenSession mavenSession, MojoDescriptor mojoDescriptor) {
+ InputLocation inputLocation =
+ mojoDescriptor.getPluginDescriptor().getPlugin().getLocation("");
+ if (inputLocation != null && inputLocation.getSource() != null) {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append(inputLocation.getSource().getModelId());
+ String location = inputLocation.getSource().getLocation();
+ if (location != null) {
+ if (location.contains("://")) {
+ stringBuilder.append(" (").append(location).append(")");
+ } else {
+ File rootBasedir = mavenSession.getTopLevelProject().getBasedir();
+ File locationFile = new File(location);
+ if (location.startsWith(rootBasedir.getPath())) {
+ stringBuilder
+ .append(" (")
+ .append(rootBasedir.toPath().relativize(locationFile.toPath()))
+ .append(")");
+ } else {
+ stringBuilder.append(" (").append(location).append(")");
+ }
+ }
+ }
+ stringBuilder.append(" @ line ").append(inputLocation.getLineNumber());
+ return stringBuilder.toString();
+ } else {
+ return "unknown";
+ }
+ }
+
+ private String pluginOccurrence(MavenSession mavenSession) {
+ MavenProject prj = mavenSession.getCurrentProject();
+ String result = prj.getGroupId() + ":" + prj.getArtifactId() + ":" + prj.getVersion();
+ File currentPom = prj.getFile();
+ if (currentPom != null) {
+ File rootBasedir = mavenSession.getTopLevelProject().getBasedir();
+ result += " (" + rootBasedir.toPath().relativize(currentPom.toPath()) + ")";
+ }
+ return result;
+ }
+
+ private String mojoInfo(MojoDescriptor mojoDescriptor, Class> mojoClass) {
+ return mojoDescriptor.getFullGoalName() + " (" + mojoClass.getName() + ")";
+ }
+
+ @SuppressWarnings("unchecked")
+ private ConcurrentHashMap pluginIssues(RepositorySystemSession session) {
+ return (ConcurrentHashMap)
+ session.getData().computeIfAbsent(ISSUES_KEY, ConcurrentHashMap::new);
+ }
+
+ private static class PluginValidationIssues {
+ private final LinkedHashSet pluginDeclarations;
+
+ private final LinkedHashSet pluginOccurrences;
+
+ private final LinkedHashSet pluginIssues;
+
+ private final LinkedHashMap> mojoIssues;
+
+ private PluginValidationIssues() {
+ this.pluginDeclarations = new LinkedHashSet<>();
+ this.pluginOccurrences = new LinkedHashSet<>();
+ this.pluginIssues = new LinkedHashSet<>();
+ this.mojoIssues = new LinkedHashMap<>();
+ }
+
+ private synchronized void reportPluginIssue(String pluginDeclaration, String pluginOccurrence, String issue) {
+ if (pluginDeclaration != null) {
+ pluginDeclarations.add(pluginDeclaration);
+ }
+ if (pluginOccurrence != null) {
+ pluginOccurrences.add(pluginOccurrence);
+ }
+ pluginIssues.add(issue);
+ }
+
+ private synchronized void reportPluginMojoIssue(
+ String pluginDeclaration, String pluginOccurrence, String mojoInfo, String issue) {
+ if (pluginDeclaration != null) {
+ pluginDeclarations.add(pluginDeclaration);
+ }
+ if (pluginOccurrence != null) {
+ pluginOccurrences.add(pluginOccurrence);
+ }
+ mojoIssues.computeIfAbsent(mojoInfo, k -> new LinkedHashSet<>()).add(issue);
+ }
+ }
+}
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedCoreExpressionValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedCoreExpressionValidator.java
index 0eea6f92ab..54bb11434d 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedCoreExpressionValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedCoreExpressionValidator.java
@@ -18,12 +18,15 @@
*/
package org.apache.maven.plugin.internal;
+import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.HashMap;
import java.util.Objects;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.PluginValidationManager;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
@@ -40,7 +43,7 @@ class DeprecatedCoreExpressionValidator extends AbstractMavenPluginParametersVal
private static final HashMap DEPRECATED_CORE_PARAMETERS;
private static final String ARTIFACT_REPOSITORY_REASON =
- "Avoid use of ArtifactRepository type. If you need access to local repository, switch to '${repositorySystemSession}' expression and get LRM from it instead.";
+ "ArtifactRepository type is deprecated and its use in Mojos should be avoided.";
static {
HashMap deprecatedCoreParameters = new HashMap<>();
@@ -49,21 +52,33 @@ class DeprecatedCoreExpressionValidator extends AbstractMavenPluginParametersVal
DEPRECATED_CORE_PARAMETERS = deprecatedCoreParameters;
}
+ @Inject
+ DeprecatedCoreExpressionValidator(PluginValidationManager pluginValidationManager) {
+ super(pluginValidationManager);
+ }
+
@Override
protected String getParameterLogReason(Parameter parameter) {
- return "is deprecated core expression; " + DEPRECATED_CORE_PARAMETERS.get(parameter.getDefaultValue());
+ return "uses deprecated parameter expression '" + parameter.getDefaultValue() + "': "
+ + DEPRECATED_CORE_PARAMETERS.get(parameter.getDefaultValue());
}
@Override
protected void doValidate(
+ MavenSession mavenSession,
MojoDescriptor mojoDescriptor,
+ Class> mojoClass,
PlexusConfiguration pomConfiguration,
ExpressionEvaluator expressionEvaluator) {
if (mojoDescriptor.getParameters() == null) {
return;
}
- mojoDescriptor.getParameters().stream().filter(this::isDeprecated).forEach(this::logParameter);
+ mojoDescriptor.getParameters().stream()
+ .filter(this::isDeprecated)
+ .map(this::formatParameter)
+ .forEach(m -> pluginValidationManager.reportPluginMojoValidationIssue(
+ mavenSession, mojoDescriptor, mojoClass, m));
}
private boolean isDeprecated(Parameter parameter) {
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java
index 96f94df87b..1fd07a10e8 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java
@@ -18,9 +18,12 @@
*/
package org.apache.maven.plugin.internal;
+import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.PluginValidationManager;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.shared.utils.logging.MessageUtils;
@@ -35,6 +38,12 @@
@Singleton
@Named
class DeprecatedPluginValidator extends AbstractMavenPluginDescriptorSourcedParametersValidator {
+
+ @Inject
+ DeprecatedPluginValidator(PluginValidationManager pluginValidationManager) {
+ super(pluginValidationManager);
+ }
+
@Override
protected String getParameterLogReason(Parameter parameter) {
return "is deprecated: " + parameter.getDeprecated();
@@ -42,36 +51,46 @@ protected String getParameterLogReason(Parameter parameter) {
@Override
protected void doValidate(
+ MavenSession mavenSession,
MojoDescriptor mojoDescriptor,
+ Class> mojoClass,
PlexusConfiguration pomConfiguration,
ExpressionEvaluator expressionEvaluator) {
if (mojoDescriptor.getDeprecated() != null) {
- logDeprecatedMojo(mojoDescriptor);
+ pluginValidationManager.reportPluginMojoValidationIssue(
+ mavenSession, mojoDescriptor, mojoClass, logDeprecatedMojo(mojoDescriptor));
}
- mojoDescriptor.getParameters().stream()
- .filter(parameter -> parameter.getDeprecated() != null)
- .filter(Parameter::isEditable)
- .forEach(parameter -> checkParameter(parameter, pomConfiguration, expressionEvaluator));
+ if (mojoDescriptor.getParameters() != null) {
+ mojoDescriptor.getParameters().stream()
+ .filter(parameter -> parameter.getDeprecated() != null)
+ .filter(Parameter::isEditable)
+ .forEach(parameter -> checkParameter(
+ mavenSession, mojoDescriptor, mojoClass, parameter, pomConfiguration, expressionEvaluator));
+ }
}
private void checkParameter(
- Parameter parameter, PlexusConfiguration pomConfiguration, ExpressionEvaluator expressionEvaluator) {
+ MavenSession mavenSession,
+ MojoDescriptor mojoDescriptor,
+ Class> mojoClass,
+ Parameter parameter,
+ PlexusConfiguration pomConfiguration,
+ ExpressionEvaluator expressionEvaluator) {
PlexusConfiguration config = pomConfiguration.getChild(parameter.getName(), false);
if (isValueSet(config, expressionEvaluator)) {
- logParameter(parameter);
+ pluginValidationManager.reportPluginMojoValidationIssue(
+ mavenSession, mojoDescriptor, mojoClass, formatParameter(parameter));
}
}
- private void logDeprecatedMojo(MojoDescriptor mojoDescriptor) {
- String message = MessageUtils.buffer()
+ private String logDeprecatedMojo(MojoDescriptor mojoDescriptor) {
+ return MessageUtils.buffer()
.warning("Goal '")
.warning(mojoDescriptor.getGoal())
.warning("' is deprecated: ")
.warning(mojoDescriptor.getDeprecated())
.toString();
-
- logger.warn(message);
}
}
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/Maven2DependenciesValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/Maven2DependenciesValidator.java
new file mode 100644
index 0000000000..7e53bd40d2
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/Maven2DependenciesValidator.java
@@ -0,0 +1,63 @@
+/*
+ * 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.plugin.internal;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.PluginValidationManager;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.codehaus.plexus.component.repository.ComponentDependency;
+
+/**
+ * Detects Maven2 plugins.
+ *
+ * @since 3.9.2
+ */
+@Singleton
+@Named
+class Maven2DependenciesValidator extends AbstractMavenPluginDependenciesValidator {
+
+ @Inject
+ Maven2DependenciesValidator(PluginValidationManager pluginValidationManager) {
+ super(pluginValidationManager);
+ }
+
+ @Override
+ protected void doValidate(MavenSession mavenSession, MojoDescriptor mojoDescriptor) {
+ Set maven2Versions = mojoDescriptor.getPluginDescriptor().getDependencies().stream()
+ .filter(d -> "org.apache.maven".equals(d.getGroupId()))
+ .filter(d -> !expectedProvidedScopeExclusions.contains(d.getGroupId() + ":" + d.getArtifactId()))
+ .map(ComponentDependency::getVersion)
+ .filter(v -> v.startsWith("2."))
+ .collect(Collectors.toSet());
+
+ if (!maven2Versions.isEmpty()) {
+ pluginValidationManager.reportPluginValidationIssue(
+ mavenSession,
+ mojoDescriptor,
+ "Plugin is a Maven 2.x plugin, which will be not supported in Maven 4.x");
+ }
+ }
+}
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenMixedDependenciesValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenMixedDependenciesValidator.java
new file mode 100644
index 0000000000..e881fc08bc
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenMixedDependenciesValidator.java
@@ -0,0 +1,60 @@
+/*
+ * 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.plugin.internal;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.PluginValidationManager;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.codehaus.plexus.component.repository.ComponentDependency;
+
+/**
+ * Detects mixed Maven versions in plugins.
+ *
+ * @since 3.9.2
+ */
+@Singleton
+@Named
+class MavenMixedDependenciesValidator extends AbstractMavenPluginDependenciesValidator {
+
+ @Inject
+ MavenMixedDependenciesValidator(PluginValidationManager pluginValidationManager) {
+ super(pluginValidationManager);
+ }
+
+ @Override
+ protected void doValidate(MavenSession mavenSession, MojoDescriptor mojoDescriptor) {
+ Set mavenVersions = mojoDescriptor.getPluginDescriptor().getDependencies().stream()
+ .filter(d -> "org.apache.maven".equals(d.getGroupId()))
+ .filter(d -> !expectedProvidedScopeExclusions.contains(d.getGroupId() + ":" + d.getArtifactId()))
+ .map(ComponentDependency::getVersion)
+ .collect(Collectors.toSet());
+
+ if (mavenVersions.size() > 1) {
+ pluginValidationManager.reportPluginValidationIssue(
+ mavenSession, mojoDescriptor, "Plugin mixes multiple Maven versions: " + mavenVersions);
+ }
+ }
+}
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginConfigurationValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginConfigurationValidator.java
index a79550c6fd..cb0e3fb23b 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginConfigurationValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginConfigurationValidator.java
@@ -18,6 +18,7 @@
*/
package org.apache.maven.plugin.internal;
+import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.configuration.PlexusConfiguration;
@@ -29,10 +30,12 @@
*/
interface MavenPluginConfigurationValidator {
/**
- * Check mojo configuration.
+ * Checks mojo configuration issues.
*/
void validate(
+ MavenSession mavenSession,
MojoDescriptor mojoDescriptor,
+ Class> mojoClass,
PlexusConfiguration pomConfiguration,
ExpressionEvaluator expressionEvaluator);
}
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginDependenciesValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginDependenciesValidator.java
new file mode 100644
index 0000000000..b990bfe58a
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginDependenciesValidator.java
@@ -0,0 +1,34 @@
+/*
+ * 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.plugin.internal;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+
+/**
+ * Service responsible for validating plugin dependencies.
+ *
+ * @since 3.9.2
+ */
+interface MavenPluginDependenciesValidator {
+ /**
+ * Checks mojo dependency issues.
+ */
+ void validate(MavenSession mavenSession, MojoDescriptor mojoDescriptor);
+}
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenScopeDependenciesValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenScopeDependenciesValidator.java
new file mode 100644
index 0000000000..87aaa8f8e0
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenScopeDependenciesValidator.java
@@ -0,0 +1,62 @@
+/*
+ * 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.plugin.internal;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.PluginValidationManager;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+
+/**
+ * Detects Maven3 artifacts in bad scope in plugins.
+ *
+ * @since 3.9.2
+ */
+@Singleton
+@Named
+class MavenScopeDependenciesValidator extends AbstractMavenPluginDependenciesValidator {
+
+ @Inject
+ MavenScopeDependenciesValidator(PluginValidationManager pluginValidationManager) {
+ super(pluginValidationManager);
+ }
+
+ @Override
+ protected void doValidate(MavenSession mavenSession, MojoDescriptor mojoDescriptor) {
+ Set mavenArtifacts = mojoDescriptor.getPluginDescriptor().getDependencies().stream()
+ .filter(d -> "org.apache.maven".equals(d.getGroupId()))
+ .filter(d -> !expectedProvidedScopeExclusions.contains(d.getGroupId() + ":" + d.getArtifactId()))
+ .filter(d -> d.getVersion().startsWith("3."))
+ .map(d -> d.getGroupId() + ":" + d.getArtifactId() + ":" + d.getVersion())
+ .collect(Collectors.toSet());
+
+ if (!mavenArtifacts.isEmpty()) {
+ pluginValidationManager.reportPluginValidationIssue(
+ mavenSession,
+ mojoDescriptor,
+ "Plugin should declare these Maven artifacts in `provided` scope: " + mavenArtifacts);
+ }
+ }
+}
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusContainerDefaultDependenciesValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusContainerDefaultDependenciesValidator.java
new file mode 100644
index 0000000000..c326fede5a
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusContainerDefaultDependenciesValidator.java
@@ -0,0 +1,53 @@
+/*
+ * 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.plugin.internal;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.PluginValidationManager;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+
+/**
+ * Detects Plexus Container Default in plugins.
+ *
+ * @since 3.9.2
+ */
+@Singleton
+@Named
+class PlexusContainerDefaultDependenciesValidator extends AbstractMavenPluginDependenciesValidator {
+
+ @Inject
+ PlexusContainerDefaultDependenciesValidator(PluginValidationManager pluginValidationManager) {
+ super(pluginValidationManager);
+ }
+
+ protected void doValidate(MavenSession mavenSession, MojoDescriptor mojoDescriptor) {
+ boolean pcdPresent = mojoDescriptor.getPluginDescriptor().getDependencies().stream()
+ .filter(d -> "org.codehaus.plexus".equals(d.getGroupId()))
+ .anyMatch(d -> "plexus-container-default".equals(d.getArtifactId()));
+
+ if (pcdPresent) {
+ pluginValidationManager.reportPluginValidationIssue(
+ mavenSession, mojoDescriptor, "Plugin depends on plexus-container-default, which is EOL");
+ }
+ }
+}
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/ReadOnlyPluginParametersValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/ReadOnlyPluginParametersValidator.java
index 6c15550797..83df41d0f7 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/ReadOnlyPluginParametersValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/ReadOnlyPluginParametersValidator.java
@@ -18,9 +18,12 @@
*/
package org.apache.maven.plugin.internal;
+import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.PluginValidationManager;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
@@ -34,6 +37,12 @@
@Named
@Singleton
class ReadOnlyPluginParametersValidator extends AbstractMavenPluginDescriptorSourcedParametersValidator {
+
+ @Inject
+ ReadOnlyPluginParametersValidator(PluginValidationManager pluginValidationManager) {
+ super(pluginValidationManager);
+ }
+
@Override
protected String getParameterLogReason(Parameter parameter) {
return "is read-only, must not be used in configuration";
@@ -41,7 +50,9 @@ protected String getParameterLogReason(Parameter parameter) {
@Override
protected void doValidate(
+ MavenSession mavenSession,
MojoDescriptor mojoDescriptor,
+ Class> mojoClass,
PlexusConfiguration pomConfiguration,
ExpressionEvaluator expressionEvaluator) {
if (mojoDescriptor.getParameters() == null) {
@@ -50,15 +61,22 @@ protected void doValidate(
mojoDescriptor.getParameters().stream()
.filter(parameter -> !parameter.isEditable())
- .forEach(parameter -> checkParameter(parameter, pomConfiguration, expressionEvaluator));
+ .forEach(parameter -> checkParameter(
+ mavenSession, mojoDescriptor, mojoClass, parameter, pomConfiguration, expressionEvaluator));
}
private void checkParameter(
- Parameter parameter, PlexusConfiguration pomConfiguration, ExpressionEvaluator expressionEvaluator) {
+ MavenSession mavenSession,
+ MojoDescriptor mojoDescriptor,
+ Class> mojoClass,
+ Parameter parameter,
+ PlexusConfiguration pomConfiguration,
+ ExpressionEvaluator expressionEvaluator) {
PlexusConfiguration config = pomConfiguration.getChild(parameter.getName(), false);
if (isValueSet(config, expressionEvaluator)) {
- logParameter(parameter);
+ pluginValidationManager.reportPluginMojoValidationIssue(
+ mavenSession, mojoDescriptor, mojoClass, formatParameter(parameter));
}
}
}