From 3864a987bbfa1cd4aa0b671fb536e62bd98e1d0b Mon Sep 17 00:00:00 2001 From: Elliotte Rusty Harold Date: Wed, 22 Jul 2026 15:03:19 +0000 Subject: [PATCH 1/2] Remove unnecessary static synchronization in ToolchainMojo Fixes #174 The static LOCK object and synchronized block around toolchainManagerPrivate.storeToolchainToBuildContext() are unnecessary because: 1. The plugin is marked threadSafe=true, meaning Maven may execute it concurrently for different modules/sessions 2. storeToolchainToBuildContext() stores data into the build context, which is already per-session and thread-safe 3. The static lock introduces unnecessary contention: one module's toolchain selection blocks another unrelated module's selection, defeating the purpose of threadSafe=true In multi-module Maven builds where the toolchains plugin runs in multiple modules, the static lock serializes what could otherwise run in parallel, slowing down builds. --- .../org/apache/maven/plugins/toolchain/ToolchainMojo.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/org/apache/maven/plugins/toolchain/ToolchainMojo.java b/src/main/java/org/apache/maven/plugins/toolchain/ToolchainMojo.java index d8454f6..8944b0b 100644 --- a/src/main/java/org/apache/maven/plugins/toolchain/ToolchainMojo.java +++ b/src/main/java/org/apache/maven/plugins/toolchain/ToolchainMojo.java @@ -46,8 +46,6 @@ configurator = "toolchains-requirement-configurator", threadSafe = true) public class ToolchainMojo extends AbstractMojo { - private static final Object LOCK = new Object(); - /** */ @Component @@ -144,9 +142,7 @@ protected boolean selectToolchain(String type, Map params) throw getLog().info("Found matching toolchain for type " + type + ": " + tc); // store matching toolchain to build context - synchronized (LOCK) { - toolchainManagerPrivate.storeToolchainToBuildContext(tc, session); - } + toolchainManagerPrivate.storeToolchainToBuildContext(tc, session); return true; } From 86860306f6f9bc0f5950273b1bba681c9d4e6c92 Mon Sep 17 00:00:00 2001 From: Elliotte Rusty Harold Date: Wed, 22 Jul 2026 15:21:43 +0000 Subject: [PATCH 2/2] Add unit tests for SelectJdkToolchainMojo version matching Refs #167 Add tests that verify the behavior of the private matches() method in SelectJdkToolchainMojo for the VERSION key, using reflection to avoid changing source code visibility. Tests confirm that RequirementMatcherFactory.createVersionMatcher() is called with the correct argument order: - createVersionMatcher(tcVal).matches(reqVal) where tcVal is the toolchain's concrete version and reqVal is the user's requirement (which may be a range). --- .../jdk/SelectJdkToolchainMojoTest.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/test/java/org/apache/maven/plugins/toolchain/jdk/SelectJdkToolchainMojoTest.java diff --git a/src/test/java/org/apache/maven/plugins/toolchain/jdk/SelectJdkToolchainMojoTest.java b/src/test/java/org/apache/maven/plugins/toolchain/jdk/SelectJdkToolchainMojoTest.java new file mode 100644 index 0000000..5a4aacf --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/toolchain/jdk/SelectJdkToolchainMojoTest.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.plugins.toolchain.jdk; + +import java.lang.reflect.Method; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.VERSION; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SelectJdkToolchainMojoTest { + + private static Method matchesMethod; + + @BeforeAll + static void setUp() throws Exception { + matchesMethod = + SelectJdkToolchainMojo.class.getDeclaredMethod("matches", String.class, String.class, String.class); + matchesMethod.setAccessible(true); + } + + private boolean invokeMatches(String key, String reqVal, String tcVal) throws Exception { + return (boolean) matchesMethod.invoke(new SelectJdkToolchainMojo(), key, reqVal, tcVal); + } + + @Test + void versionRangeShouldMatchToolchainVersion() throws Exception { + // reqVal is the user's requirement (e.g., version range), tcVal is the toolchain's provided version + assertTrue(invokeMatches(VERSION, "[11,17)", "11.0.1")); + } + + @Test + void exactVersionShouldMatchToolchainVersion() throws Exception { + assertTrue(invokeMatches(VERSION, "11.0.1", "11.0.1")); + } + + @Test + void versionRangeShouldRejectToolchainVersionOutsideRange() throws Exception { + assertFalse(invokeMatches(VERSION, "[11,17)", "17.0.1")); + } +}