Skip to content

Fix matching against one of multiple env-variables pointing to one JDK#148

Open
HannesWell wants to merge 1 commit into
apache:masterfrom
HannesWell:fix-multi-env-variable-matching
Open

Fix matching against one of multiple env-variables pointing to one JDK#148
HannesWell wants to merge 1 commit into
apache:masterfrom
HannesWell:fix-multi-env-variable-matching

Conversation

@HannesWell

@HannesWell HannesWell commented Mar 10, 2026

Copy link
Copy Markdown
Contributor

The arguments when matching the collected env-variables pointing to one JDK against the required one were mistakenly swapped. This had the effect that the 'env'-variable match always failed when more than one env variable points to the same JDK.

This happens if in an environment multiple JDKs are available through structured environment variables (e.g. JAVA_17_HOME, JAVA_21_HOME, JAVA_25_HOME) and one of them is used as 'main' JDK and therefore JAVA_HOME also points to it.

As long as only one env variable points to a JDK, this error does not make a difference.

Following this checklist to help us incorporate your
contribution quickly and easily:

  • Your pull request should address just one issue, without pulling in other changes.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Each commit in the pull request should have a meaningful subject line and body.
    Note that commits might be squashed by a maintainer on merge.
  • Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied.
    This may not always be possible but is a best-practice.
  • Run mvn verify to make sure basic checks pass.
    A more thorough check will be performed on your pull request automatically.
  • You have run the integration tests successfully (mvn -Prun-its verify).

If your pull request is about ~20 lines of code you don't need to sign an
Individual Contributor License Agreement if you are unsure
please ask on the developers list.

To make clear that you license your contribution under
the Apache License Version 2.0, January 2004
you have to acknowledge this by using the following check-box.

@HannesWell

Copy link
Copy Markdown
Contributor Author

@gnodet you have written that part, could you please have a look?
This can really make life difficult.

return RequirementMatcherFactory.createVersionMatcher(tcVal).matches(reqVal);
case ENV:
return reqVal.matches("(.*,|^)\\Q" + tcVal + "\\E(,.*|$)");
return tcVal.matches("(.*,|^)\\Q" + reqVal + "\\E(,.*|$)");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a unit test will be appreciated for such code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I already wanted to add one.
But I found only one very basic test for this at all and setting up a complete new test infrastructure for this was a bit too much work for me at the moment. :/

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a second look and maybe it's simpler than assumed. And I oversaw the IT tests.
But I assume a unit test would be possible relatively easy.
I'm looking into it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unit test will be enough, I'm fine to make method package protected and simply test it,
eg. we can provide many examples by parameterized test

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've now figured out how to setup an integration test (and handle the trickery of Windows path with back-slashes).

Setting up a unit test would probably also be possible with the adjustments you mentioned, but since the most relevant part of the logic is in the Mojo, would again need more non trivial test setup.

@HannesWell HannesWell force-pushed the fix-multi-env-variable-matching branch from ce0b039 to 22768cc Compare March 11, 2026 19:04
@HannesWell

Copy link
Copy Markdown
Contributor Author

@slawekjaranowski can we proceed with this PR now that it also has integration tests?

@HannesWell

HannesWell commented Mar 17, 2026

Copy link
Copy Markdown
Contributor Author

Most of the workflows are canceled due to timeouts after a very short time and a successful build.
One build is fully successful and one build fails.
Can anyone help with that?

@slawekjaranowski

Copy link
Copy Markdown
Member

Most of the workflows are canceled due to timeouts after a very short time and a successful build. One build is fully successful and one build fails. Can anyone help with that?

looks like fail on JDK 8

Comment thread src/it/select-jdk-env-multi/invoker.properties Outdated
Comment thread pom.xml Outdated
<goals>
<goal>regex-property</goal>
</goals>
<!-- Prevent it-test failures on Windows due to interpretation of back-slashes in paths.-->

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks strange ... how it will be in real environments ... users on Windows will have such values

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no clue. But if you can tell me how to do it properly, I'm happy to change/remove that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be not needed at all, tollchains can be executed on windows as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fails the execution on Windows because the back-slashes used on Windows are interpreted as escape characters when the properties file of the invoker-plugin is read.
E.g. a value of

invoker.environmentVariables.JAVA_X_HOME = C:\abc\def\ghi

(Probably) similar to "C:\abc\def\ghi" being an invalid string literal in Java such value is not properly read from that properties file, which leads to a JAVA_X_HOME env variable with null value and subsequently fails the ToolchainDiscoverer execution.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when we have in invoker properties

invoker.environmentVariables.JAVA_X_HOME = ${env.JAVA_HOME}

properties doesn't contains any escape character, it is evaluated in invoker code after reading

@HannesWell HannesWell May 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used exactly that initially but it failed on my Windows computer with the error below.
But I'll apply the suggested change and if the CI is happy I'm happy too.

[ERROR] -------------------------------------------------
[ERROR]

*** begin build.log for: select-jdk-env-multi\pom.xml ***
Apache Maven 3.9.14 (996c630dbc656c76214ce58821dcc58be960875b)
Maven home: C:\maven-3.9.14
Java version: 25.0.2, vendor: Eclipse Adoptium, runtime: C:\java\temurin-jdk-25.0.2+10
Default locale: de_DE, platform encoding: UTF-8
OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"
[DEBUG] Created new class realm maven.api
[DEBUG] Importing foreign packages into class realm maven.api
[DEBUG]   Imported: javax.annotation.* < plexus.core
[DEBUG]   Imported: javax.annotation.security.* < plexus.core
[DEBUG]   Imported: javax.inject.* < plexus.core
[DEBUG]   Imported: org.apache.maven.* < plexus.core
[DEBUG]   Imported: org.apache.maven.artifact < plexus.core
[DEBUG]   Imported: org.apache.maven.classrealm < plexus.core
[DEBUG]   Imported: org.apache.maven.cli < plexus.core
[DEBUG]   Imported: org.apache.maven.configuration < plexus.core
[DEBUG]   Imported: org.apache.maven.exception < plexus.core
[DEBUG]   Imported: org.apache.maven.execution < plexus.core
[DEBUG]   Imported: org.apache.maven.execution.scope < plexus.core
[DEBUG]   Imported: org.apache.maven.graph < plexus.core
[DEBUG]   Imported: org.apache.maven.lifecycle < plexus.core
[DEBUG]   Imported: org.apache.maven.model < plexus.core
[DEBUG]   Imported: org.apache.maven.monitor < plexus.core
[DEBUG]   Imported: org.apache.maven.plugin < plexus.core
[DEBUG]   Imported: org.apache.maven.profiles < plexus.core
[DEBUG]   Imported: org.apache.maven.project < plexus.core
[DEBUG]   Imported: org.apache.maven.reporting < plexus.core
[DEBUG]   Imported: org.apache.maven.repository < plexus.core
[DEBUG]   Imported: org.apache.maven.rtinfo < plexus.core
[DEBUG]   Imported: org.apache.maven.settings < plexus.core
[DEBUG]   Imported: org.apache.maven.toolchain < plexus.core
[DEBUG]   Imported: org.apache.maven.usability < plexus.core
[DEBUG]   Imported: org.apache.maven.wagon.* < plexus.core
[DEBUG]   Imported: org.apache.maven.wagon.authentication < plexus.core
[DEBUG]   Imported: org.apache.maven.wagon.authorization < plexus.core
[DEBUG]   Imported: org.apache.maven.wagon.events < plexus.core
[DEBUG]   Imported: org.apache.maven.wagon.observers < plexus.core
[DEBUG]   Imported: org.apache.maven.wagon.proxy < plexus.core
[DEBUG]   Imported: org.apache.maven.wagon.repository < plexus.core
[DEBUG]   Imported: org.apache.maven.wagon.resource < plexus.core
[DEBUG]   Imported: org.codehaus.classworlds < plexus.core
[DEBUG]   Imported: org.codehaus.plexus.* < plexus.core
[DEBUG]   Imported: org.codehaus.plexus.classworlds < plexus.core
[DEBUG]   Imported: org.codehaus.plexus.component < plexus.core
[DEBUG]   Imported: org.codehaus.plexus.configuration < plexus.core
[DEBUG]   Imported: org.codehaus.plexus.container < plexus.core
[DEBUG]   Imported: org.codehaus.plexus.context < plexus.core
[DEBUG]   Imported: org.codehaus.plexus.lifecycle < plexus.core
[DEBUG]   Imported: org.codehaus.plexus.logging < plexus.core
[DEBUG]   Imported: org.codehaus.plexus.personality < plexus.core
[DEBUG]   Imported: org.codehaus.plexus.util.xml.Xpp3Dom < plexus.core
[DEBUG]   Imported: org.codehaus.plexus.util.xml.pull.XmlPullParser < plexus.core
[DEBUG]   Imported: org.codehaus.plexus.util.xml.pull.XmlPullParserException < plexus.core
[DEBUG]   Imported: org.codehaus.plexus.util.xml.pull.XmlSerializer < plexus.core
[DEBUG]   Imported: org.eclipse.aether.* < plexus.core
[DEBUG]   Imported: org.eclipse.aether.artifact < plexus.core
[DEBUG]   Imported: org.eclipse.aether.collection < plexus.core
[DEBUG]   Imported: org.eclipse.aether.deployment < plexus.core
[DEBUG]   Imported: org.eclipse.aether.graph < plexus.core
[DEBUG]   Imported: org.eclipse.aether.impl < plexus.core
[DEBUG]   Imported: org.eclipse.aether.installation < plexus.core
[DEBUG]   Imported: org.eclipse.aether.internal.impl < plexus.core
[DEBUG]   Imported: org.eclipse.aether.metadata < plexus.core
[DEBUG]   Imported: org.eclipse.aether.repository < plexus.core
[DEBUG]   Imported: org.eclipse.aether.resolution < plexus.core
[DEBUG]   Imported: org.eclipse.aether.spi < plexus.core
[DEBUG]   Imported: org.eclipse.aether.transfer < plexus.core
[DEBUG]   Imported: org.eclipse.aether.util < plexus.core
[DEBUG]   Imported: org.eclipse.aether.version < plexus.core
[DEBUG]   Imported: org.fusesource.jansi.* < plexus.core
[DEBUG]   Imported: org.slf4j.* < plexus.core
[DEBUG]   Imported: org.slf4j.event.* < plexus.core
[DEBUG]   Imported: org.slf4j.helpers.* < plexus.core
[DEBUG]   Imported: org.slf4j.spi.* < plexus.core
[DEBUG] Populating class realm maven.api
[DEBUG] Created adapter factory; available factories [file-lock, rwlock-local, semaphore-local, noop]; available name mappers [discriminating, file-gaecv, file-gav, file-hgaecv, file-hgav, file-static, gaecv, gav, static]
[INFO] Error stacktraces are turned on.
[DEBUG] Message scheme: plain
[DEBUG] Reading global settings from C:\maven-3.9.14\conf\settings.xml
[DEBUG] Reading user settings from C:\git\apache.maven-toolchains-plugin\target\it\interpolated-settings.xml
[DEBUG] Reading global toolchains from C:\maven-3.9.14\conf\toolchains.xml
[DEBUG] Reading user toolchains from C:\User\.m2\toolchains.xml
[DEBUG] Using local repository at C:\git\apache.maven-toolchains-plugin\target\local-repo
[DEBUG] Using manager EnhancedLocalRepositoryManager with priority 10.0 for C:\git\apache.maven-toolchains-plugin\target\local-repo
[INFO] Scanning for projects...
[DEBUG] Extension realms for project org.apache.maven.plugins.toolchains.its:select-jdk-env-multi:jar:1.0-SNAPSHOT: (none)
[DEBUG] Looking up lifecycle mappings for packaging jar from ClassRealm[plexus.core, parent: null]
[DEBUG] === REACTOR BUILD PLAN ================================================
[DEBUG] Project: org.apache.maven.plugins.toolchains.its:select-jdk-env-multi:jar:1.0-SNAPSHOT
[DEBUG] Tasks:   [compile]
[DEBUG] Style:   Regular
[DEBUG] =======================================================================
[INFO]
[INFO] ----< org.apache.maven.plugins.toolchains.its:select-jdk-env-multi >----
[INFO] Building maven-toolchains-plugin IT: select jdk toolchain test with environment variable 1.0-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[DEBUG] Lifecycle clean -> [pre-clean, clean, post-clean]
[DEBUG] Lifecycle default -> [validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy]
[DEBUG] Lifecycle site -> [pre-site, site, post-site, site-deploy]
[DEBUG] Creating adapter using nameMapper 'gaecv' and factory 'rwlock-local'
[DEBUG] Skipped remote request for org.apache.maven.plugins:maven-toolchains-plugin:3.2.1-SNAPSHOT/maven-metadata.xml locally installed metadata up-to-date
[DEBUG] Skipped remote request for org.apache.maven.plugins:maven-toolchains-plugin:3.2.1-SNAPSHOT/maven-metadata.xml locally installed metadata up-to-date
[DEBUG] Lifecycle clean -> [pre-clean, clean, post-clean]
[DEBUG] Lifecycle default -> [validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy]
[DEBUG] Lifecycle site -> [pre-site, site, post-site, site-deploy]
[DEBUG] Lifecycle clean -> [pre-clean, clean, post-clean]
[DEBUG] Lifecycle default -> [validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy]
[DEBUG] Lifecycle site -> [pre-site, site, post-site, site-deploy]
[DEBUG] Lifecycle clean -> [pre-clean, clean, post-clean]
[DEBUG] Lifecycle default -> [validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy]
[DEBUG] Lifecycle site -> [pre-site, site, post-site, site-deploy]
[DEBUG] === PROJECT BUILD PLAN ================================================
[DEBUG] Project:       org.apache.maven.plugins.toolchains.its:select-jdk-env-multi:1.0-SNAPSHOT
[DEBUG] Dependencies (collect): []
[DEBUG] Dependencies (resolve): [compile]
[DEBUG] Repositories (dependencies): [local.central (file:///C:/User/.m2/repository, default, releases+snapshots), central (https://repo.maven.apache.org/maven2, default, releases)]
[DEBUG] Repositories (plugins)     : [local.central (file:///C:/User/.m2/repository, default, releases+snapshots), central (https://repo.maven.apache.org/maven2, default, releases)]
[DEBUG] -----------------------------------------------------------------------
[DEBUG] Goal:          org.apache.maven.plugins:maven-toolchains-plugin:3.2.1-SNAPSHOT:select-jdk-toolchain (default)
[DEBUG] Style:         Regular
[DEBUG] Configuration: <?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <comparator default-value="lts,current,env,version,vendor">${toolchain.jdk.comparator}</comparator>
  <discoverToolchains default-value="true">${toolchain.jdk.discover}</discoverToolchains>
  <env>JAVA_X_HOME</env>
  <runtimeName>${toolchain.jdk.runtime.name}</runtimeName>
  <runtimeVersion>${toolchain.jdk.runtime.version}</runtimeVersion>
  <useJdk default-value="IfMatch">${toolchain.jdk.mode}</useJdk>
  <vendor>${toolchain.jdk.vendor}</vendor>
  <version>${toolchain.jdk.version}</version>
</configuration>
[DEBUG] -----------------------------------------------------------------------
[DEBUG] Goal:          org.apache.maven.plugins:maven-resources-plugin:3.4.0:resources (default-resources)
[DEBUG] Style:         Regular
[DEBUG] Configuration: <?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <addDefaultExcludes default-value="true"/>
  <buildFilters default-value="${project.build.filters}"/>
  <encoding default-value="${project.build.sourceEncoding}"/>
  <escapeWindowsPaths default-value="true"/>
  <fileNameFiltering default-value="false"/>
  <includeEmptyDirs default-value="false"/>
  <outputDirectory default-value="${project.build.outputDirectory}"/>
  <overwrite default-value="false"/>
  <project default-value="${project}"/>
  <resources default-value="${project.resources}"/>
  <session default-value="${session}"/>
  <skip default-value="false">${maven.resources.skip}</skip>
  <supportMultiLineFiltering default-value="false"/>
  <useBuildFilters default-value="true"/>
  <useDefaultDelimiters default-value="true"/>
</configuration>
[DEBUG] -----------------------------------------------------------------------
[DEBUG] Goal:          org.apache.maven.plugins:maven-compiler-plugin:3.15.0:compile (default-compile)
[DEBUG] Style:         Regular
[DEBUG] Configuration: <?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <annotationProcessorPathsUseDepMgmt default-value="false"/>
  <basedir default-value="${basedir}"/>
  <buildDirectory default-value="${project.build.directory}"/>
  <compilePath default-value="${project.compileClasspathElements}"/>
  <compileSourceRoots default-value="${project.compileSourceRoots}"/>
  <compilerId default-value="javac">${maven.compiler.compilerId}</compilerId>
  <compilerReuseStrategy default-value="${reuseCreated}">${maven.compiler.compilerReuseStrategy}</compilerReuseStrategy>
  <compilerVersion>${maven.compiler.compilerVersion}</compilerVersion>
  <createMissingPackageInfoClass default-value="true">${maven.compiler.createMissingPackageInfoClass}</createMissingPackageInfoClass>
  <debug default-value="true">${maven.compiler.debug}</debug>
  <debugFileName default-value="javac"/>
  <debuglevel>${maven.compiler.debuglevel}</debuglevel>
  <enablePreview default-value="false">${maven.compiler.enablePreview}</enablePreview>
  <encoding default-value="${project.build.sourceEncoding}">${encoding}</encoding>
  <executable>${maven.compiler.executable}</executable>
  <failOnError default-value="true">${maven.compiler.failOnError}</failOnError>
  <failOnWarning default-value="false">${maven.compiler.failOnWarning}</failOnWarning>
  <fileExtensions default-value="class,jar"/>
  <forceJavacCompilerUse default-value="false">${maven.compiler.forceJavacCompilerUse}</forceJavacCompilerUse>
  <forceLegacyJavacApi default-value="false">${maven.compiler.forceLegacyJavacApi}</forceLegacyJavacApi>
  <fork default-value="false">${maven.compiler.fork}</fork>
  <generatedSourcesDirectory default-value="${project.build.directory}/generated-sources/annotations"/>
  <implicit>${maven.compiler.implicit}</implicit>
  <maxmem>${maven.compiler.maxmem}</maxmem>
  <meminitial>${maven.compiler.meminitial}</meminitial>
  <moduleVersion default-value="${project.version}">${maven.compiler.moduleVersion}</moduleVersion>
  <mojoExecution default-value="${mojoExecution}"/>
  <optimize default-value="false">${maven.compiler.optimize}</optimize>
  <outputDirectory default-value="${project.build.outputDirectory}">${maven.compiler.outputDirectory}</outputDirectory>
  <outputTimestamp default-value="${project.build.outputTimestamp}"/>
  <parameters default-value="false">${maven.compiler.parameters}</parameters>
  <proc>${maven.compiler.proc}</proc>
  <project default-value="${project}"/>
  <projectArtifact default-value="${project.artifact}"/>
  <release>${maven.compiler.release}</release>
  <session default-value="${session}"/>
  <showCompilationChanges default-value="false">${maven.compiler.showCompilationChanges}</showCompilationChanges>
  <showDeprecation default-value="false">${maven.compiler.showDeprecation}</showDeprecation>
  <showWarnings default-value="true">${maven.compiler.showWarnings}</showWarnings>
  <skipMain>${maven.main.skip}</skipMain>
  <skipMultiThreadWarning default-value="false">${maven.compiler.skipMultiThreadWarning}</skipMultiThreadWarning>
  <source default-value="1.8">${maven.compiler.source}</source>
  <staleMillis default-value="0">${lastModGranularityMs}</staleMillis>
  <target default-value="1.8">${maven.compiler.target}</target>
  <useIncrementalCompilation default-value="true">${maven.compiler.useIncrementalCompilation}</useIncrementalCompilation>
  <useModuleVersion default-value="true">${maven.compiler.useModuleVersion}</useModuleVersion>
  <verbose default-value="false">${maven.compiler.verbose}</verbose>
</configuration>
[DEBUG] =======================================================================
[DEBUG] Dependency collection stats {ConflictMarker.analyzeTime=17400, ConflictMarker.markTime=37700, ConflictMarker.nodeCount=1, ConflictIdSorter.graphTime=7700, ConflictIdSorter.topsortTime=267500, ConflictIdSorter.conflictIdCount=0, ConflictIdSorter.conflictIdCycleCount=0, ConflictResolver.totalTime=767700, ConflictResolver.conflictItemCount=0, DfDependencyCollector.collectTime=71700, DfDependencyCollector.transformTime=1913600}
[DEBUG] org.apache.maven.plugins.toolchains.its:select-jdk-env-multi:jar:1.0-SNAPSHOT
[INFO]
[INFO] --- toolchains:3.2.1-SNAPSHOT:select-jdk-toolchain (default) @ select-jdk-env-multi ---
[DEBUG] Dependency collection stats {ConflictMarker.analyzeTime=404700, ConflictMarker.markTime=39600, ConflictMarker.nodeCount=4, ConflictIdSorter.graphTime=34600, ConflictIdSorter.topsortTime=11200, ConflictIdSorter.conflictIdCount=4, ConflictIdSorter.conflictIdCycleCount=0, ConflictResolver.totalTime=925300, ConflictResolver.conflictItemCount=4, DfDependencyCollector.collectTime=19769900, DfDependencyCollector.transformTime=1428300}
[DEBUG] org.apache.maven.plugins:maven-toolchains-plugin:jar:3.2.1-SNAPSHOT
[DEBUG]    org.codehaus.plexus:plexus-xml:jar:3.0.1:compile
[DEBUG]    org.slf4j:slf4j-api:jar:1.7.36:compile
[DEBUG]    javax.inject:javax.inject:jar:1:compile
[DEBUG] Created new class realm plugin>org.apache.maven.plugins:maven-toolchains-plugin:3.2.1-SNAPSHOT
[DEBUG] Importing foreign packages into class realm plugin>org.apache.maven.plugins:maven-toolchains-plugin:3.2.1-SNAPSHOT
[DEBUG]   Imported:  < maven.api
[DEBUG] Populating class realm plugin>org.apache.maven.plugins:maven-toolchains-plugin:3.2.1-SNAPSHOT
[DEBUG]   Included: org.apache.maven.plugins:maven-toolchains-plugin:jar:3.2.1-SNAPSHOT
[DEBUG]   Included: org.codehaus.plexus:plexus-xml:jar:3.0.1
[DEBUG] Loading mojo org.apache.maven.plugins:maven-toolchains-plugin:3.2.1-SNAPSHOT:select-jdk-toolchain from plugin realm ClassRealm[plugin>org.apache.maven.plugins:maven-toolchains-plugin:3.2.1-SNAPSHOT, parent: jdk.internal.loader.ClassLoaders$AppClassLoader@5bc2b487]
[DEBUG] Configuring mojo execution 'org.apache.maven.plugins:maven-toolchains-plugin:3.2.1-SNAPSHOT:select-jdk-toolchain:default' with basic configurator -->
[DEBUG]   (f) comparator = lts,current,env,version,vendor
[DEBUG]   (f) discoverToolchains = true
[DEBUG]   (f) env = JAVA_X_HOME
[DEBUG]   (f) useJdk = IfMatch
[DEBUG] -- end configuration --
[DEBUG] Toolchain JDK[C:\java\temurin-jdk-25.0.2+10] is missing required property: env
[DEBUG] Toolchain JDK[C:\java\temurin-jdk8u372-b07] is missing required property: env
[DEBUG] Toolchain JDK[C:\java\graalvm-ce-java11-22.3.2] is missing required property: env
[DEBUG] Toolchain JDK[C:\java\graalvm-ce-java17.0.7+7.1] is missing required property: env
[DEBUG] Toolchain JDK[C:\java\temurin-jdk-21.0.6+7] is missing required property: env
[DEBUG] Toolchain JDK[C:\java\temurin-jdk-25.0.2+10] is missing required property: env
[DEBUG] No matching toolchains configured, trying to discover JDK toolchains
[INFO] Found 1 possible jdks: [C:\java\temurin-jdk-25.0.2+10]
[WARNING] Error discovering toolchains: java.lang.NullPointerException: Cannot invoke "java.nio.file.Path.toRealPath(java.nio.file.LinkOption[])" because "path" is null
java.lang.NullPointerException: Cannot invoke "java.nio.file.Path.toRealPath(java.nio.file.LinkOption[])" because "path" is null
    at org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.getCanonicalPath (ToolchainDiscoverer.java:319)
    at org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.getCanonicalPath (ToolchainDiscoverer.java:321)
    at org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.lambda$discoverToolchains$2 (ToolchainDiscoverer.java:144)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.accept (ForEachOps.java:186)
    at java.util.stream.ReferencePipeline$2$1.accept (ReferencePipeline.java:197)
    at java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet.lambda$entryConsumer$0 (Collections.java:1783)
    at java.util.Iterator.forEachRemaining (Iterator.java:133)
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining (Spliterators.java:1939)
    at java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntrySetSpliterator.forEachRemaining (Collections.java:1808)
    at java.util.stream.AbstractPipeline.copyInto (AbstractPipeline.java:570)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto (AbstractPipeline.java:560)
    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential (ForEachOps.java:153)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential (ForEachOps.java:176)
    at java.util.stream.AbstractPipeline.evaluate (AbstractPipeline.java:265)
    at java.util.stream.ReferencePipeline.forEach (ReferencePipeline.java:632)
    at org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.discoverToolchains (ToolchainDiscoverer.java:143)
    at org.apache.maven.plugins.toolchain.jdk.SelectJdkToolchainMojo.doExecute (SelectJdkToolchainMojo.java:203)
    at org.apache.maven.plugins.toolchain.jdk.SelectJdkToolchainMojo.execute (SelectJdkToolchainMojo.java:164)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:126)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:328)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:316)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:212)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:174)
    at org.apache.maven.lifecycle.internal.MojoExecutor.access$000 (MojoExecutor.java:75)
    at org.apache.maven.lifecycle.internal.MojoExecutor$1.run (MojoExecutor.java:162)
    at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute (DefaultMojosExecutionStrategy.java:39)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:159)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:105)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:73)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:53)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:118)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:261)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:173)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:101)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:919)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:285)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:207)
    at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:104)
    at java.lang.reflect.Method.invoke (Method.java:565)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:255)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:201)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:361)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:314)
[DEBUG] Discovered 0 JDK toolchains
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.227 s
[INFO] Finished at: 2026-05-08T10:25:16+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-toolchains-plugin:3.2.1-SNAPSHOT:select-jdk-toolchain (default) on project select-jdk-env-multi: Cannot find matching toolchain definitions for the following toolchain types:{env=JAVA_X_HOME}
[ERROR] Define the required toolchains in your ~/.m2/toolchains.xml file.
[ERROR] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-toolchains-plugin:3.2.1-SNAPSHOT:select-jdk-toolchain (default) on project select-jdk-env-multi: Cannot find matching toolchain definitions for the following toolchain types:{env=JAVA_X_HOME}
Define the required toolchains in your ~/.m2/toolchains.xml file.
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:333)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:316)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:212)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:174)
    at org.apache.maven.lifecycle.internal.MojoExecutor.access$000 (MojoExecutor.java:75)
    at org.apache.maven.lifecycle.internal.MojoExecutor$1.run (MojoExecutor.java:162)
    at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute (DefaultMojosExecutionStrategy.java:39)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:159)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:105)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:73)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:53)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:118)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:261)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:173)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:101)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:919)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:285)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:207)
    at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:104)
    at java.lang.reflect.Method.invoke (Method.java:565)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:255)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:201)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:361)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:314)
Caused by: org.apache.maven.plugin.MojoFailureException: Cannot find matching toolchain definitions for the following toolchain types:{env=JAVA_X_HOME}
Define the required toolchains in your ~/.m2/toolchains.xml file.
    at org.apache.maven.plugins.toolchain.jdk.SelectJdkToolchainMojo.doExecute (SelectJdkToolchainMojo.java:219)
    at org.apache.maven.plugins.toolchain.jdk.SelectJdkToolchainMojo.execute (SelectJdkToolchainMojo.java:164)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:126)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:328)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:316)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:212)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:174)
    at org.apache.maven.lifecycle.internal.MojoExecutor.access$000 (MojoExecutor.java:75)
    at org.apache.maven.lifecycle.internal.MojoExecutor$1.run (MojoExecutor.java:162)
    at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute (DefaultMojosExecutionStrategy.java:39)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:159)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:105)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:73)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:53)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:118)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:261)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:173)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:101)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:919)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:285)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:207)
    at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:104)
    at java.lang.reflect.Method.invoke (Method.java:565)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:255)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:201)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:361)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:314)
[ERROR]
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

failed in the same way also on linux sys

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I looked into it in detail and it turned out I was on a wrong track (don't recall anymore why I assumed it's a Windows path issue).

In fact the problem seems that the invoker-plugin does not interpolate access to env variables and only considers only a limited set of properties (e.g. not java.home).
But it does consider properties defined in a pom (or CLI), so just defining the property <JAVA_HOME>${env.JAVA_HOME}</JAVA_HOME> solved it for me locally and the integration tests succeeded.
Alternatively

but just adding one property seems the simplest solution for me.

@slawekjaranowski I hope that the CLI succeeds now.

@HannesWell HannesWell force-pushed the fix-multi-env-variable-matching branch from 22768cc to c781061 Compare March 24, 2026 08:12
@HannesWell

Copy link
Copy Markdown
Contributor Author

@slawekjaranowski can we proceed here and could you rerun the failed builds?
I cannot tell how this change is actually related to the failure.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes environment-variable based JDK matching when multiple JAVA*_HOME variables point to the same JDK, and adds an integration test to cover the scenario.

Changes:

  • Correct ENV requirement matching by swapping the operands in the regex check.
  • Add a new invoker-based integration test covering multiple env vars pointing to one JDK.
  • Add a run-its profile helper to sanitize java.home for Windows path handling in ITs.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/main/java/org/apache/maven/plugins/toolchain/jdk/SelectJdkToolchainMojo.java Fixes ENV matching logic so required env var names are matched against the toolchain’s collected env-var list.
src/it/select-jdk-env-multi/pom.xml Adds a new IT project invoking select-jdk-toolchain with an env requirement.
src/it/select-jdk-env-multi/invoker.properties Sets up multiple JAVA*_HOME variables pointing to the same JDK for the IT.
pom.xml Adds a run-its profile step to sanitize java.home for use in invoker environment variables (Windows-friendly).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/it/select-jdk-env-multi/pom.xml Outdated
Comment thread src/it/select-jdk-env-multi/invoker.properties Outdated
@HannesWell HannesWell force-pushed the fix-multi-env-variable-matching branch 2 times, most recently from 7c570a3 to a20d2a2 Compare May 8, 2026 08:29
The arguments when matching the collected env-variables pointing to one
JDK against the required one were mistakenly swapped.
This had the effect that the 'env'-variable match always failed when
more than one env variable points to the same JDK.
@HannesWell HannesWell force-pushed the fix-multi-env-variable-matching branch from a20d2a2 to 428df47 Compare May 8, 2026 18:55
@HannesWell

Copy link
Copy Markdown
Contributor Author

@slawekjaranowski the verification builds are now all successful.
Is this now ready? It would be great, if this were part of the next release.

@slawekjaranowski slawekjaranowski self-assigned this May 16, 2026
@HannesWell

Copy link
Copy Markdown
Contributor Author

@slawekjaranowski, any updates on this in the meantime? :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants