{"record":{"id":"2a492da9649f6beb","repo":"apache/maven","slug":"java-toolchain-without-the-jdkhome-configuration-e-2a492d","errorCode":null,"errorMessage":"Java toolchain without the jdkHome configuration element.","messagePattern":"Java toolchain without the jdkHome configuration element\\.","errorType":"validation","errorClass":"ToolchainFactoryException","httpStatus":null,"severity":"error","filePath":"impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultJavaToolchainFactory.java","lineNumber":81,"sourceCode":"    @Override\n    public JavaToolchain createToolchain(@Nonnull ToolchainModel model) {\n        // populate the provides section\n        Map<String, Predicate<String>> matchers = model.getProvides().entrySet().stream()\n                .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, entry -> {\n                    String key = entry.getKey();\n                    String value = entry.getValue();\n                    if (value == null) {\n                        throw new ToolchainFactoryException(\n                                \"Provides token '\" + key + \"' doesn't have any value configured.\");\n                    }\n                    return \"version\".equals(key) ? new VersionMatcher(versionParser, value) : new ExactMatcher(value);\n                }));\n\n        // compute and normalize the java home\n        XmlNode dom = model.getConfiguration();\n        XmlNode javahome = dom != null ? dom.child(KEY_JAVAHOME) : null;\n        if (javahome == null || javahome.value() == null) {\n            throw new ToolchainFactoryException(\n                    \"Java toolchain without the \" + KEY_JAVAHOME + \" configuration element.\");\n        }\n        Path normal = Paths.get(javahome.value()).normalize();\n        if (!Files.exists(normal)) {\n            throw new ToolchainFactoryException(\"Non-existing JDK home configuration at \" + normal.toAbsolutePath());\n        }\n        String javaHome = normal.toString();\n\n        Version javaVersion = model.getProvides().entrySet().stream()\n                .filter(entry -> \"version\".equals(entry.getKey()))\n                .map(Map.Entry::getValue)\n                .map(versionParser::parseVersion)\n                .findAny()\n                .orElse(null);\n\n        return new DefaultJavaToolchain(model, javaHome, javaVersion, matchers);\n    }\n","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultJavaToolchainFactory.java#L63-L99","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"<!-- before -->\n<toolchain>\n  <type>jdk</type>\n  <provides><version>17</version></provides>\n  <configuration/>\n</toolchain>\n\n<!-- after -->\n<toolchain>\n  <type>jdk</type>\n  <provides><version>17</version></provides>\n  <configuration>\n    <jdkHome>/usr/lib/jvm/temurin-17</jdkHome>\n  </configuration>\n</toolchain>","handlingStrategy":"validation","validationCode":"XmlNode cfg = model.getConfiguration();\nXmlNode jdkHome = cfg != null ? cfg.child('jdkHome') : null;\nif (jdkHome == null || jdkHome.value() == null || jdkHome.value().isBlank()) {\n    throw new IllegalArgumentException('jdk toolchain requires <configuration><jdkHome>...</jdkHome></configuration>');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["maven","toolchains","configuration","jdk"],"backgroundTag":"toolchain-misconfiguration","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}