apache/maven · error · ToolchainFactoryException
Java toolchain without the jdkHome configuration element.
Error message
Java toolchain without the jdkHome configuration element.
What it means
When building a JDK toolchain, DefaultJavaToolchainFactory requires a <jdkHome> child element inside the toolchain's <configuration> block in toolchains.xml. If configuration is missing entirely, or has no jdkHome element, or the element has no text value, creation fails with ToolchainFactoryException. jdkHome is the only mandatory configuration element for the jdk toolchain type.
Source
Thrown at impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultJavaToolchainFactory.java:81
@Override
public JavaToolchain createToolchain(@Nonnull ToolchainModel model) {
// populate the provides section
Map<String, Predicate<String>> matchers = model.getProvides().entrySet().stream()
.collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, entry -> {
String key = entry.getKey();
String value = entry.getValue();
if (value == null) {
throw new ToolchainFactoryException(
"Provides token '" + key + "' doesn't have any value configured.");
}
return "version".equals(key) ? new VersionMatcher(versionParser, value) : new ExactMatcher(value);
}));
// compute and normalize the java home
XmlNode dom = model.getConfiguration();
XmlNode javahome = dom != null ? dom.child(KEY_JAVAHOME) : null;
if (javahome == null || javahome.value() == null) {
throw new ToolchainFactoryException(
"Java toolchain without the " + KEY_JAVAHOME + " configuration element.");
}
Path normal = Paths.get(javahome.value()).normalize();
if (!Files.exists(normal)) {
throw new ToolchainFactoryException("Non-existing JDK home configuration at " + normal.toAbsolutePath());
}
String javaHome = normal.toString();
Version javaVersion = model.getProvides().entrySet().stream()
.filter(entry -> "version".equals(entry.getKey()))
.map(Map.Entry::getValue)
.map(versionParser::parseVersion)
.findAny()
.orElse(null);
return new DefaultJavaToolchain(model, javaHome, javaVersion, matchers);
}
View on GitHub (pinned to e4093d4e12)
Solutions
- Add <configuration><jdkHome>/path/to/jdk</jdkHome></configuration> inside the jdk toolchain element
- Verify the element name is exactly jdkHome (case-sensitive) with a non-empty text value
- Replace unexpanded ${...} placeholders with a literal path or ensure the property is available when toolchains.xml is read
Example fix
<!-- before -->
<toolchain>
<type>jdk</type>
<provides><version>17</version></provides>
<configuration/>
</toolchain>
<!-- after -->
<toolchain>
<type>jdk</type>
<provides><version>17</version></provides>
<configuration>
<jdkHome>/usr/lib/jvm/temurin-17</jdkHome>
</configuration>
</toolchain> Defensive patterns
Strategy: validation
Validate before calling
XmlNode cfg = model.getConfiguration();
XmlNode jdkHome = cfg != null ? cfg.child('jdkHome') : null;
if (jdkHome == null || jdkHome.value() == null || jdkHome.value().isBlank()) {
throw new IllegalArgumentException('jdk toolchain requires <configuration><jdkHome>...</jdkHome></configuration>');
} Prevention
- Use exactly <jdkHome> inside <configuration> for jdk toolchains
- Avoid unexpanded ${...} placeholders in toolchains.xml
- Validate the file structure with mvn toolchains:display or a lint step before builds
When it happens
Trigger: A toolchains.xml <toolchain><type>jdk</type> entry with an empty <configuration/>, a misspelled element like <javaHome> or <jdk>, or a jdkHome element whose value comes from an unexpanded property leaving it empty.
Common situations: First-time toolchains.xml setup following outdated docs that use different element names; property placeholders (${env.JAVA_HOME}) not being interpolated in toolchains.xml; copying a .NET-style or custom toolchain template; Maven 3 to 4 migrations where the file was never completed.
Related errors
- Java toolchain without the jdkHome configuration element.
- Provides token '" + key + "' doesn't have any value configur
- Only fully-qualified sets allowed in multiple set scenario:
- Single version must be surrounded by []: {}
- Cannot read toolchains file at " + userToolchainsFile.getAbs
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/2a492da9649f6beb.
Report an issue: GitHub.