From 1b675fb7c1cc057ef5adb606a42894bc423242f0 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Tue, 28 Jul 2026 22:31:44 +0200 Subject: [PATCH 1/3] 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. --- ...PluginDescriptorRequirementsValidator.java | 62 +++++++++++++ ...inDescriptorRequirementsValidatorTest.java | 88 +++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 impl/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java create mode 100644 impl/maven-core/src/test/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidatorTest.java diff --git a/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java b/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java new file mode 100644 index 000000000000..faf499c7ae33 --- /dev/null +++ b/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.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 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; + +/** + * 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 = 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 use Plexus Component (plugin tools {@code @Component} annotation). " + + "Maven 4 Dependency Injection (for v4 plugins) or JSR 330 annotations (for v3 plugins) to inject dependencies should be used instead."); + } + } +} diff --git a/impl/maven-core/src/test/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidatorTest.java b/impl/maven-core/src/test/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidatorTest.java new file mode 100644 index 000000000000..9fb4ce7f8bd4 --- /dev/null +++ b/impl/maven-core/src/test/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidatorTest.java @@ -0,0 +1,88 @@ +/* + * 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.Collections; +import java.util.List; + +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.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class PluginDescriptorRequirementsValidatorTest { + + @Mock + private PluginValidationManager pluginValidationManager; + + @Mock + private MavenSession mavenSession; + + @Mock + private MojoDescriptor mojoDescriptor; + + @InjectMocks + private PluginDescriptorRequirementsValidator validator; + + private final Class mojoClass = PluginDescriptorRequirementsValidatorTest.class; + + @Test + void testValidateReportsIssueWhenMojoHasRequirements() { + when(mojoDescriptor.getRequirements()).thenReturn(List.of(new ComponentRequirement())); + + validator.validate(mavenSession, mojoDescriptor, mojoClass, null, null); + + verify(pluginValidationManager) + .reportPluginMojoValidationIssue( + eq(PluginValidationManager.IssueLocality.EXTERNAL), + eq(mavenSession), + eq(mojoDescriptor), + eq(mojoClass), + contains("Plugin use Plexus Component")); + } + + @Test + void testValidateDoesNotReportIssueWhenMojoHasNoRequirements() { + when(mojoDescriptor.getRequirements()).thenReturn(Collections.emptyList()); + + 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)); + } +} From 08f26113abe99168b77e72acae90d6233e5713a5 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Tue, 28 Jul 2026 23:00:49 +0200 Subject: [PATCH 2/3] Apply review comments --- .../internal/PluginDescriptorRequirementsValidator.java | 4 ++-- .../internal/PluginDescriptorRequirementsValidatorTest.java | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java b/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java index faf499c7ae33..6f64d012d7e9 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java +++ b/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java @@ -55,8 +55,8 @@ public void validate( mavenSession, mojoDescriptor, mojoClass, - "Plugin use Plexus Component (plugin tools {@code @Component} annotation). " - + "Maven 4 Dependency Injection (for v4 plugins) or JSR 330 annotations (for v3 plugins) to inject dependencies should be used instead."); + "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/impl/maven-core/src/test/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidatorTest.java b/impl/maven-core/src/test/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidatorTest.java index 9fb4ce7f8bd4..13350969bc56 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidatorTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidatorTest.java @@ -34,7 +34,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.contains; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -68,7 +67,7 @@ void testValidateReportsIssueWhenMojoHasRequirements() { eq(mavenSession), eq(mojoDescriptor), eq(mojoClass), - contains("Plugin use Plexus Component")); + contains("Plugin uses Plexus Component requirements")); } @Test From 6860c99e0944bb4f2657b61d7689607cbb5d0f68 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Thu, 30 Jul 2026 19:25:02 +0200 Subject: [PATCH 3/3] Add requireNonNull in constructor --- .../internal/PluginDescriptorRequirementsValidator.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java b/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java index 6f64d012d7e9..6e95324013e6 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java +++ b/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDescriptorRequirementsValidator.java @@ -28,6 +28,8 @@ 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. */ @@ -39,7 +41,7 @@ class PluginDescriptorRequirementsValidator implements MavenPluginConfigurationV @Inject PluginDescriptorRequirementsValidator(PluginValidationManager pluginValidationManager) { - this.pluginValidationManager = pluginValidationManager; + this.pluginValidationManager = requireNonNull(pluginValidationManager); } @Override