Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -72,21 +72,64 @@ DefaultToolchainManagerV4 v4Manager() {
return new DefaultToolchainManagerV4();
}

private org.apache.maven.impl.DefaultToolchainManager getDelegate() {
return getToolchainManager(lookup, logger);
@Provides
@Typed(ToolchainFactory.class)
@Named("jdk")
ToolchainFactory jdkFactory() {
return createV3FactoryBridge("jdk");
}

/**
* Creates a v3 ToolchainFactory bridge that wraps a v4 ToolchainFactory.
*/
public ToolchainFactory createV3FactoryBridge(String type) {
try {
org.apache.maven.api.services.ToolchainFactory v4Factory =
lookup.lookup(org.apache.maven.api.services.ToolchainFactory.class, type);
if (v4Factory == null) {
return null;
}
return createV3FactoryBridgeForV4Factory(v4Factory);
} catch (Exception e) {
// If lookup fails, no v4 factory exists for this type
return null;
}
}

private org.apache.maven.impl.DefaultToolchainManager getToolchainManager(Lookup lookup, Logger logger) {
return getToolchainManager(
lookup.lookupMap(ToolchainFactory.class),
lookup.lookupMap(org.apache.maven.api.services.ToolchainFactory.class),
logger);
/**
* Creates a v3 ToolchainFactory bridge that wraps a specific v4 ToolchainFactory instance.
*/
public ToolchainFactory createV3FactoryBridgeForV4Factory(
org.apache.maven.api.services.ToolchainFactory v4Factory) {
return new ToolchainFactory() {
@Override
public ToolchainPrivate createToolchain(ToolchainModel model) throws MisconfiguredToolchainException {
try {
org.apache.maven.api.Toolchain v4Toolchain = v4Factory.createToolchain(model.getDelegate());
return getToolchainV3(v4Toolchain);
} catch (ToolchainFactoryException e) {
throw new MisconfiguredToolchainException(e.getMessage(), e);
}
}

@Override
public ToolchainPrivate createDefaultToolchain() {
try {
return v4Factory
.createDefaultToolchain()
.map(ToolchainManagerFactory.this::getToolchainV3)
.orElse(null);
} catch (ToolchainFactoryException e) {
return null;
}
}
};
}

private org.apache.maven.impl.DefaultToolchainManager getToolchainManager(
Map<String, ToolchainFactory> v3Factories,
Map<String, org.apache.maven.api.services.ToolchainFactory> v4Factories,
Logger logger) {
private org.apache.maven.impl.DefaultToolchainManager getDelegate() {
Map<String, ToolchainFactory> v3Factories = lookup.lookupMap(ToolchainFactory.class);
Map<String, org.apache.maven.api.services.ToolchainFactory> v4Factories =
lookup.lookupMap(org.apache.maven.api.services.ToolchainFactory.class);
Map<String, org.apache.maven.api.services.ToolchainFactory> allFactories = new HashMap<>();
for (Map.Entry<String, ToolchainFactory> entry : v3Factories.entrySet()) {
ToolchainFactory v3Factory = entry.getValue();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* 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.it;

import java.io.File;

import org.junit.jupiter.api.Test;

/**
* This is a test set for <a href="https://github.com/apache/maven/issues/11314">GH-11314</a>.
*
* Verifies that V3 Mojos can be injected with v3 API beans that are bridged from v4 API
* implementations. Specifically tests the case where a plugin needs to inject ToolchainFactory
* with a named qualifier.
*
* @see <a href="https://github.com/apache/maven-toolchains-plugin/issues/128">maven-toolchains-plugin#128</a>
*/
public class MavenITgh11314PluginInjectionTest extends AbstractMavenIntegrationTestCase {

MavenITgh11314PluginInjectionTest() {
super("[4.0.0,)");
}

/**
* Verify that V3 Mojos can be injected with v3 ToolchainFactory which is bridged from
* the v4 ToolchainFactory implementation. This test reproduces the issue where a plugin
* with a field requiring injection of ToolchainFactory with @Named("jdk") fails with
* NullInjectedIntoNonNullable error.
*
* @throws Exception in case of failure
*/
@Test
public void testV3MojoWithMavenContainerInjection() throws Exception {
File testDir = extractResources("/gh-11314-v3-mojo-injection");

// First, build and install the test plugin
File pluginDir = new File(testDir, "plugin");
Verifier pluginVerifier = newVerifier(pluginDir.getAbsolutePath(), false);
pluginVerifier.addCliArgument("install");
pluginVerifier.execute();
pluginVerifier.verifyErrorFreeLog();

// Now run the test project that uses the plugin
File consumerDir = new File(testDir, "consumer");
Verifier verifier = newVerifier(consumerDir.getAbsolutePath(), false);
verifier.addCliArguments("test:test-goal");
verifier.execute();
verifier.verifyErrorFreeLog();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public TestSuiteOrdering() {
* the tests are to finishing. Newer tests are also more likely to fail, so this is
* a fail fast technique as well.
*/
suite.addTestSuite(MavenITgh11314PluginInjectionTest.class);
suite.addTestSuite(MavenITgh2576ItrNotHonoredTest.class);
suite.addTestSuite(MavenITgh11356InvalidTransitiveRepositoryTest.class);
suite.addTestSuite(MavenITgh11280DuplicateDependencyConsumerPomTest.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.apache.maven.its.gh11314</groupId>
<artifactId>test-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>

<artifactId>consumer</artifactId>
<packaging>jar</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.its.gh11314</groupId>
<artifactId>test-plugin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<executions>
<execution>
<goals>
<goal>test-goal</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.apache.maven.its.gh11314</groupId>
<artifactId>test-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>

<artifactId>test-plugin</artifactId>
<packaging>maven-plugin</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.version>4.0.0-rc-4</maven.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>${maven.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>${maven.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
<version>${maven.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.11.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<goalPrefix>test</goalPrefix>
</configuration>
<executions>
<execution>
<id>default-descriptor</id>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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.its.gh11314;

import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.toolchain.ToolchainFactory;

/**
* A test Mojo that requires injection of ToolchainFactory from the Maven container.
* This reproduces the issue where V3 Mojos cannot be injected with v3 API beans
* when only v4 API implementations are available.
*
* Tests both named injection (@Named("jdk")) and toolchain manager functionality.
*/
@Mojo(name = "test-goal")
public class TestMojo extends AbstractMojo {

/**
* The ToolchainFactory from the Maven container.
* This field requires injection of the v3 API ToolchainFactory with "jdk" hint.
*/
@Inject
@Named("jdk")
private ToolchainFactory jdkFactory;

@Override
public void execute() throws MojoExecutionException {
if (jdkFactory == null) {
throw new MojoExecutionException("JDK ToolchainFactory was not injected!");
}
getLog().info("JDK ToolchainFactory successfully injected: "
+ jdkFactory.getClass().getName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.its.gh11314</groupId>
<artifactId>test-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<modules>
<module>plugin</module>
<module>consumer</module>
</modules>
</project>