{"record":{"id":"50027e6ea0d04092","repo":"HMCL-dev/HMCL","slug":"failed-to-get-java-info-from","errorCode":null,"errorMessage":"Failed to get Java info from ","messagePattern":"Failed to get Java info from ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/java/JavaInfoUtils.java","lineNumber":59,"sourceCode":"\n    public static @NotNull JavaInfo fromExecutable(Path executable) throws IOException {\n        assert executable.isAbsolute();\n\n        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        }","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaInfoUtils.java#L41-L77","documentation":"JavaInfoUtils.fromExecutable probes a Java executable by launching it with the bundled org.glavo.info.Main helper on the classpath and parsing its JSON output. When the helper process produces no parseable output, Gson's fromJson returns null and this IOException is thrown, meaning the executable could not yield any Java info at all. It signals that the runtime probe fundamentally failed, as distinct from a probe that succeeded but reported no version.","triggerScenarios":"Calling JavaInfoUtils.fromExecutable(Path) with an executable whose invocation of `java -classpath <hmcl.jar> org.glavo.info.Main` prints nothing or non-JSON output, causing GSON.fromJson to return null.","commonSituations":"The path points to a non-Java binary, a stub script, or a 0-byte/corrupt executable; the JRE is so stripped down it cannot run the helper class; the process crashes or is killed before emitting output; an antivirus or sandbox blocks spawning the process.","solutions":["Verify the path points to a real java executable (e.g. `java -version` runs successfully).","Run `<executable> -classpath <hmcl.jar> org.glavo.info.Main` manually and inspect stdout/stderr.","Reinstall or re-download the affected JDK/JRE, which may be corrupt or incomplete.","Check antivirus/endpoint protection or sandbox policies that block HMCL from launching child processes.","If HMCL itself is not run from a jar (thisJarPath() null case), package it as a jar so the helper classpath is valid."],"exampleFix":"// before\nJavaInfo info = JavaInfoUtils.fromExecutable(Path.of(\"/usr/bin/java-stub\"));\n// after\nPath exe = Path.of(\"/opt/jdk-17/bin/java\");\nif (Files.isRegularFile(exe) && Files.isExecutable(exe)) {\n    JavaInfo info = JavaInfoUtils.fromExecutable(exe);\n} else {\n    // fall back to directory scanning / skip this runtime\n}","handlingStrategy":"try-catch","validationCode":"Path exe = Path.of(\"/opt/jdk/bin/java\");\nif (!Files.isRegularFile(exe) || !Files.isExecutable(exe)) throw new IllegalStateException(\"not an executable: \" + exe);\n// optionally: new ProcessBuilder(exe.toString(), \"-version\").start().waitFor() == 0","typeGuard":null,"tryCatchPattern":"try {\n    JavaInfo info = JavaInfoUtils.fromExecutable(exe);\n} catch (IOException e) {\n    LOG.warning(\"Java probe failed for \" + exe + \": \" + e.getMessage());\n    // skip this runtime or fall back to another discovered installation\n}","preventionTips":["Always resolve the real java binary (bin/java, not a parent directory or wrapper stub).","Probe runtimes in a loop and skip entries whose probe throws instead of aborting.","Run the org.glavo.info.Main helper manually when debugging a failing runtime.","Watch for antivirus/EDR tools blocking child process spawns.","Ensure HMCL runs from a jar so JarUtils.thisJarPath() is non-null."],"tags":["java","process-execution","io-exception","runtime-detection"],"backgroundTag":"unexpected-api-response-shape","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"}