{"record":{"id":"909a8fa8211a2d7c","repo":"apache/maven","slug":"java-toolchain-without-the-jdkhome-configuration-e","errorCode":null,"errorMessage":"Java toolchain without the jdkHome configuration element.","messagePattern":"Java toolchain without the jdkHome configuration element\\.","errorType":"exception","errorClass":"MisconfiguredToolchainException","httpStatus":null,"severity":"error","filePath":"compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java","lineNumber":88,"sourceCode":"                throw new MisconfiguredToolchainException(\n                        \"Provides token '\" + key + \"' doesn't have any value configured.\");\n            }\n\n            RequirementMatcher matcher;\n            if (\"version\".equals(key)) {\n                matcher = RequirementMatcherFactory.createVersionMatcher(value);\n            } else {\n                matcher = RequirementMatcherFactory.createExactMatcher(value);\n            }\n\n            jtc.addProvideToken(key, matcher);\n        }\n\n        // populate the configuration section\n        Xpp3Dom dom = (Xpp3Dom) model.getConfiguration();\n        Xpp3Dom javahome = dom != null ? dom.getChild(JavaToolchainImpl.KEY_JAVAHOME) : null;\n        if (javahome == null) {\n            throw new MisconfiguredToolchainException(\n                    \"Java toolchain without the \" + JavaToolchainImpl.KEY_JAVAHOME + \" configuration element.\");\n        }\n        Path normal = Paths.get(javahome.getValue()).normalize();\n        if (Files.exists(normal)) {\n            jtc.setJavaHome(Paths.get(javahome.getValue()).normalize().toString());\n        } else {\n            throw new MisconfiguredToolchainException(\n                    \"Non-existing JDK home configuration at \" + normal.toAbsolutePath());\n        }\n\n        ArtifactVersion javaVersion = model.getProvides().entrySet().stream()\n                .filter(entry -> \"version\".equals(entry.getKey()))\n                .map(Map.Entry::getValue)\n                .map(v -> new DefaultArtifactVersion((String) v))\n                .findAny()\n                .orElse(null);\n\n        jtc.setJavaVersion(javaVersion);","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java#L70-L106","documentation":"JavaToolchainFactory requires every jdk toolchain to carry a <configuration> block containing a <jdkHome> child (JavaToolchainImpl.KEY_JAVAHOME). If the configuration DOM is absent or has no jdkHome child, MisconfiguredToolchainException('Java toolchain without the jdkHome configuration element.') is thrown before the path is even inspected.","triggerScenarios":"A toolchains.xml <toolchain><type>jdk</type> entry that omits <configuration> or whose <configuration> lacks <jdkHome> — e.g. only <provides> was filled in.","commonSituations":"Minimal hand-written toolchain entries copied from blog posts that skip the configuration section; migration from scripts that only recorded the Java version; XML indentation mistakes nesting jdkHome outside <configuration>.","solutions":["Add <configuration><jdkHome>/path/to/jdk</jdkHome></configuration> inside the jdk toolchain element","Verify jdkHome is a direct child of <configuration>, not of <toolchain> or <provides>","Point jdkHome at a JDK home directory (containing bin/java), then rerun the build using the toolchains plugin"],"exampleFix":"<!-- before -->\n<toolchain>\n  <type>jdk</type>\n  <provides>\n    <version>17</version>\n  </provides>\n</toolchain>\n\n<!-- after -->\n<toolchain>\n  <type>jdk</type>\n  <provides>\n    <version>17</version>\n  </provides>\n  <configuration>\n    <jdkHome>/usr/lib/jvm/temurin-17</jdkHome>\n  </configuration>\n</toolchain>","handlingStrategy":"validation","validationCode":"import org.apache.maven.toolchain.model.ToolchainModel;\nimport org.codehaus.plexus.util.xml.Xpp3Dom;\n\nboolean hasJdkHome(ToolchainModel model) {\n    Xpp3Dom config = (Xpp3Dom) model.getConfiguration();\n    return config != null && config.getChild(\"jdkHome\") != null;\n}\n\nif (\"jdk\".equals(model.getType()) && !hasJdkHome(model)) {\n    throw new IllegalStateException(\"jdk toolchain requires <configuration><jdkHome>...</jdkHome>\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    toolchainFactory.createToolchain(model, log);\n} catch (MisconfiguredToolchainException e) {\n    if (e.getMessage().contains(\"jdkHome configuration element\")) {\n        reportToolchainsXmlError(\"Add <configuration><jdkHome>/path/to/jdk</jdkHome></configuration>\");\n    } else {\n        throw e;\n    }\n}","preventionTips":["Use a template toolchains.xml that already contains the configuration block","After editing, run a quick toolchains smoke build (mvn -Dtoolchain=jdk toolchains:toolchain or a project requiring it) to catch config gaps early","Never split provides and configuration across separate files or profiles — the factory reads one model"],"tags":["maven","toolchains","jdk","configuration","validation"],"backgroundTag":"missing-config-value","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}