{"record":{"id":"c1c1366759d3f11f","repo":"HMCL-dev/HMCL","slug":"failed-to-get-java-version-from","errorCode":null,"errorMessage":"Failed to get Java version from ","messagePattern":"Failed to get Java version from ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/java/JavaInfoUtils.java","lineNumber":63,"sourceCode":"        Path thisPath = JarUtils.thisJarPath();\n        if (thisPath == null) {\n            throw new IOException(\"Failed to find current HMCL location\");\n        }\n\n        try {\n            Result result = JsonUtils.GSON.fromJson(SystemUtils.run(\n                    executable.toString(),\n                    \"-classpath\",\n                    thisPath.toString(),\n                    org.glavo.info.Main.class.getName()\n            ), Result.class);\n\n            if (result == null) {\n                throw new IOException(\"Failed to get Java info from \" + executable);\n            }\n\n            if (result.javaVersion == null) {\n                throw new IOException(\"Failed to get Java version from \" + executable);\n            }\n\n            Architecture architecture = Architecture.parseArchName(result.osArch);\n            Platform platform = Platform.getPlatform(OperatingSystem.CURRENT_OS,\n                    architecture != Architecture.UNKNOWN\n                            ? architecture\n                            : Architecture.SYSTEM_ARCH);\n\n            return new JavaInfo(platform, result.javaVersion, result.javaVendor);\n        } catch (IOException e) {\n            throw e;\n        } catch (Throwable e) {\n            throw new IOException(e);\n        }\n    }\n\n    @JsonSerializable\n    private record Result(@SerializedName(\"os.name\") String osName, @SerializedName(\"os.arch\") String osArch,","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaInfoUtils.java#L45-L81","documentation":"JavaInfoUtils.fromExecutable successfully ran the org.glavo.info.Main helper but its JSON output did not include a java.version property, so the parsed Result record's javaVersion field is null. This IOException distinguishes 'executable responded but reported no version' from a total probe failure. HMCL requires a version string to classify and use a Java installation, so the runtime is treated as unusable.","triggerScenarios":"Calling JavaInfoUtils.fromExecutable(Path) on a runtime whose helper output JSON lacks `java.version` (Gson leaves the record field null).","commonSituations":"Minimal/exotic JRE builds (e.g. custom, embedded, or very old runtimes) that omit or mask the java.version system property; a wrapper script that mangles the helper's JSON output; a JRE built with patched system properties.","solutions":["Run `<executable> -XshowSettings:properties -version` and confirm `java.version` is set in that runtime.","Use a standard, complete JDK/JRE build (Temurin, Zulu, Oracle, etc.) instead of the stripped/exotic runtime.","Run the helper manually (`<exe> -classpath <hmcl.jar> org.glavo.info.Main`) and inspect the emitted JSON for a missing java.version key.","Update the runtime to a newer release of the same distribution if the property is suppressed.","Catch this IOException and fall back to another discovered Java installation."],"exampleFix":"// before\nJavaInfo info = JavaInfoUtils.fromExecutable(customMinimalJrePath);\n// after\ntry {\n    JavaInfo info = JavaInfoUtils.fromExecutable(customMinimalJrePath);\n} catch (IOException e) {\n    // runtime did not report java.version; pick a known-good JDK instead\n    JavaInfo info = JavaInfoUtils.fromExecutable(Path.of(\"/usr/lib/jvm/temurin-17/bin/java\"));\n}","handlingStrategy":"try-catch","validationCode":"Process p = new ProcessBuilder(exe.toString(), \"-XshowSettings:properties\", \"-version\").redirectErrorStream(true).start();\nString out = new String(p.getInputStream().readAllBytes());\nif (!out.contains(\"java.version\")) LOG.warning(\"runtime reports no java.version: \" + exe);","typeGuard":null,"tryCatchPattern":"try {\n    return JavaInfoUtils.fromExecutable(exe);\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"Failed to get Java version\")) {\n        LOG.warning(\"Runtime lacks java.version, skipping: \" + exe);\n    }\n    return null; // or fall back to another runtime\n}","preventionTips":["Prefer complete, standard JDK distributions over minimal or custom-built JREs.","Test-probe each runtime once and cache results; exclude runtimes that fail.","Inspect `-XshowSettings:properties` output for exotic runtimes before trusting them.","Keep runtimes up to date; old/exotic builds may suppress system properties.","Never hand-patch system properties in custom JRE builds used with HMCL."],"tags":["java","runtime-detection","missing-property","io-exception"],"backgroundTag":"empty-required-field","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}