From a5f2e4b2551281e0a826484f39746f01db58e80c Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Fri, 31 Jul 2026 16:01:33 +0200 Subject: [PATCH 1/2] Add validation for Plexus-based plugin dependency injection What changed - Added a new validation that detects outdated dependency injection usage in plugins. - Added a clear warning for plugin developers when this pattern is found. - Pointed users to the recommended modern injection approach. based on: 2a8b6b243ea1b87c76b5eec9bd8a375d5361706f --- maven-core/pom.xml | 5 ++ ...PluginDescriptorRequirementsValidator.java | 64 +++++++++++++++ ...inDescriptorRequirementsValidatorTest.java | 81 +++++++++++++++++++ pom.xml | 6 ++ 4 files changed, 156 insertions(+) create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java create mode 100644 maven-core/src/test/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidatorTest.java diff --git a/maven-core/pom.xml b/maven-core/pom.xml index 764050bde790..d0eb50439915 100644 --- a/maven-core/pom.xml +++ b/maven-core/pom.xml @@ -163,6 +163,11 @@ under the License. mockito-core test + + org.mockito + mockito-junit-jupiter + test + org.junit.jupiter junit-jupiter-api diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java new file mode 100644 index 000000000000..6e95324013e6 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java @@ -0,0 +1,64 @@ +/* + * 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; +import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; +import org.codehaus.plexus.configuration.PlexusConfiguration; + +import static java.util.Objects.requireNonNull; + +/** + * Verify that plugin descriptor does not contain Plexus Component requirements. + */ +@Singleton +@Named +class PluginDescriptorRequirementsValidator implements MavenPluginConfigurationValidator { + + protected final PluginValidationManager pluginValidationManager; + + @Inject + PluginDescriptorRequirementsValidator(PluginValidationManager pluginValidationManager) { + this.pluginValidationManager = requireNonNull(pluginValidationManager); + } + + @Override + public void validate( + MavenSession mavenSession, + MojoDescriptor mojoDescriptor, + Class mojoClass, + PlexusConfiguration pomConfiguration, + ExpressionEvaluator expressionEvaluator) { + if (!mojoDescriptor.getRequirements().isEmpty()) { + pluginValidationManager.reportPluginMojoValidationIssue( + PluginValidationManager.IssueLocality.EXTERNAL, + mavenSession, + mojoDescriptor, + mojoClass, + "Plugin uses Plexus Component requirements (@Component annotation). " + + "Use Maven 4 Dependency Injection (for v4 plugins) or JSR 330 annotations (for v3 plugins) to inject dependencies instead."); + } + } +} diff --git a/maven-core/src/test/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidatorTest.java b/maven-core/src/test/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidatorTest.java new file mode 100644 index 000000000000..5e08558b0e30 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidatorTest.java @@ -0,0 +1,81 @@ +/* + * 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.PluginValidationManager; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.codehaus.plexus.component.repository.ComponentRequirement; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.contains; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +public class PluginDescriptorRequirementsValidatorTest { + + @Mock + private PluginValidationManager pluginValidationManager; + + @Mock + private MavenSession mavenSession; + + @InjectMocks + private PluginDescriptorRequirementsValidator validator; + + private final Class mojoClass = PluginDescriptorRequirementsValidatorTest.class; + + @Test + public void testValidateReportsIssueWhenMojoHasRequirements() { + MojoDescriptor mojoDescriptor = new MojoDescriptor(); + mojoDescriptor.addRequirement(new ComponentRequirement()); + + validator.validate(mavenSession, mojoDescriptor, mojoClass, null, null); + + verify(pluginValidationManager) + .reportPluginMojoValidationIssue( + eq(PluginValidationManager.IssueLocality.EXTERNAL), + eq(mavenSession), + eq(mojoDescriptor), + eq(mojoClass), + contains("Plugin uses Plexus Component requirements")); + } + + @Test + public void testValidateDoesNotReportIssueWhenMojoHasNoRequirements() { + MojoDescriptor mojoDescriptor = new MojoDescriptor(); + + validator.validate(mavenSession, mojoDescriptor, mojoClass, null, null); + + verify(pluginValidationManager, never()) + .reportPluginMojoValidationIssue( + any(PluginValidationManager.IssueLocality.class), + any(MavenSession.class), + any(MojoDescriptor.class), + any(Class.class), + any(String.class)); + } +} diff --git a/pom.xml b/pom.xml index eb7f74274106..d0e550a86cac 100644 --- a/pom.xml +++ b/pom.xml @@ -497,6 +497,12 @@ under the License. ${mockitoVersion} test + + org.mockito + mockito-junit-jupiter + ${mockitoVersion} + test + org.xmlunit xmlunit-core From b37f3e6668aea7257f0f638c054c42b7b569ed7e Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Fri, 31 Jul 2026 16:31:39 +0200 Subject: [PATCH 2/2] Apply review comments --- .../internal/PluginDescriptorRequirementsValidator.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java index 6e95324013e6..e18914906195 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java @@ -32,12 +32,14 @@ /** * Verify that plugin descriptor does not contain Plexus Component requirements. + * + * @since 3.10.0 */ @Singleton @Named class PluginDescriptorRequirementsValidator implements MavenPluginConfigurationValidator { - protected final PluginValidationManager pluginValidationManager; + private final PluginValidationManager pluginValidationManager; @Inject PluginDescriptorRequirementsValidator(PluginValidationManager pluginValidationManager) {