{"record":{"id":"322984a399dfc47f","repo":"HMCL-dev/HMCL","slug":"missing-java-version","errorCode":null,"errorMessage":"Missing Java version","messagePattern":"Missing Java version","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/java/JavaInfo.java","lineNumber":83,"sourceCode":"        String osName = properties.get(\"OS_NAME\");\n        String osArch = properties.get(\"OS_ARCH\");\n        String vendor = properties.get(\"IMPLEMENTOR\");\n\n        OperatingSystem os = \"\".equals(osName) && \"OpenJDK BSD Porting Team\".equals(vendor)\n                ? OperatingSystem.FREEBSD\n                : OperatingSystem.parseOSName(osName);\n\n        Architecture arch = Architecture.parseArchName(osArch);\n        String javaVersion = properties.get(\"JAVA_VERSION\");\n\n        if (os == OperatingSystem.UNKNOWN)\n            throw new IOException(\"Unknown operating system: \" + osName);\n\n        if (arch == Architecture.UNKNOWN)\n            throw new IOException(\"Unknown architecture: \" + osArch);\n\n        if (javaVersion == null)\n            throw new IOException(\"Missing Java version\");\n\n        return new JavaInfo(Platform.getPlatform(os, arch), javaVersion, vendor);\n    }\n\n    public static <F, E extends ArchiveEntry> JavaInfo fromArchive(ArchiveFileTree<F, E> tree) throws IOException {\n        if (tree.getRoot().getSubDirs().size() != 1 || !tree.getRoot().getFiles().isEmpty())\n            throw new IOException();\n\n        ArchiveFileTree.Dir<E> jdkRoot = tree.getRoot().getSubDirs().values().iterator().next();\n        E releaseEntry = jdkRoot.getFiles().get(\"release\");\n        if (releaseEntry == null)\n            throw new IOException(\"Missing release file\");\n\n        JavaInfo info;\n        try (BufferedReader reader = new BufferedReader(new InputStreamReader(tree.getInputStream(releaseEntry), StandardCharsets.UTF_8))) {\n            info = JavaInfo.fromReleaseFile(reader);\n        }\n","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/java/JavaInfo.java#L65-L101","documentation":"JavaInfo.fromReleaseFile() requires the JAVA_VERSION property from the release file to determine the Java version string. When the property is absent or null, it throws IOException(\"Missing Java version\") — HMCL cannot report or compare the runtime's version without it.","triggerScenarios":"Reading a release file that lacks the JAVA_VERSION entry entirely (empty properties, minimal jlink/custom runtime image, or a truncated/corrupted release file).","commonSituations":"Custom jlink runtime images built without jdeps/release metadata; hand-crafted release files; some old or vendor-stripped JREs; a release file actually pointing to a directory that isn't a Java installation at all.","solutions":["Use a complete JDK/JRE distribution whose release file contains JAVA_VERSION","Regenerate the jlink image with --release-info or copy JAVA_VERSION into the release file","Point the Java scan at the real java executable's installation directory, not a wrapper directory","Catch the IOException during scanning and mark the Java installation as unknown/invalid"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"Properties rel = new Properties();\nrel.load(Files.newInputStream(javaHome.resolve(\"release\")));\nif (rel.getProperty(\"JAVA_VERSION\") == null) {\n    skipThisJavaInstallation(); // will otherwise throw\n}","typeGuard":null,"tryCatchPattern":"try {\n    JavaInfo info = JavaInfo.fromReleaseFile(javaHome);\n} catch (IOException e) {\n    markJavaUnknownVersion(javaHome); // fallback: probe `java -version`\n}","preventionTips":["Use JDK/JRE distributions that ship complete release files","Regenerate jlink images including release metadata","Fall back to `java -version` output when the release file lacks JAVA_VERSION","Validate the release file during setup of custom runtimes"],"tags":["java-runtime","parsing","configuration"],"backgroundTag":"missing-required-config-field","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}