HMCL-dev/HMCL · error · IOException

Failed to get Java info from

Error message

Failed to get Java info from 

What it means

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.

Solutions

  1. Verify the path points to a real java executable (e.g. `java -version` runs successfully).
  2. Run `<executable> -classpath <hmcl.jar> org.glavo.info.Main` manually and inspect stdout/stderr.
  3. Reinstall or re-download the affected JDK/JRE, which may be corrupt or incomplete.
  4. Check antivirus/endpoint protection or sandbox policies that block HMCL from launching child processes.
  5. If HMCL itself is not run from a jar (thisJarPath() null case), package it as a jar so the helper classpath is valid.

Example fix

// before
JavaInfo info = JavaInfoUtils.fromExecutable(Path.of("/usr/bin/java-stub"));
// after
Path exe = Path.of("/opt/jdk-17/bin/java");
if (Files.isRegularFile(exe) && Files.isExecutable(exe)) {
    JavaInfo info = JavaInfoUtils.fromExecutable(exe);
} else {
    // fall back to directory scanning / skip this runtime
}
Defensive patterns

Strategy: try-catch

Validate before calling

Path exe = Path.of("/opt/jdk/bin/java");
if (!Files.isRegularFile(exe) || !Files.isExecutable(exe)) throw new IllegalStateException("not an executable: " + exe);
// optionally: new ProcessBuilder(exe.toString(), "-version").start().waitFor() == 0

Try / catch

try {
    JavaInfo info = JavaInfoUtils.fromExecutable(exe);
} catch (IOException e) {
    LOG.warning("Java probe failed for " + exe + ": " + e.getMessage());
    // skip this runtime or fall back to another discovered installation
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/50027e6ea0d04092. Report an issue: GitHub.

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/java/JavaInfoUtils.java:59

    public static @NotNull JavaInfo fromExecutable(Path executable) throws IOException {
        assert executable.isAbsolute();

        Path thisPath = JarUtils.thisJarPath();
        if (thisPath == null) {
            throw new IOException("Failed to find current HMCL location");
        }

        try {
            Result result = JsonUtils.GSON.fromJson(SystemUtils.run(
                    executable.toString(),
                    "-classpath",
                    thisPath.toString(),
                    org.glavo.info.Main.class.getName()
            ), Result.class);

            if (result == null) {
                throw new IOException("Failed to get Java info from " + executable);
            }

            if (result.javaVersion == null) {
                throw new IOException("Failed to get Java version from " + executable);
            }

            Architecture architecture = Architecture.parseArchName(result.osArch);
            Platform platform = Platform.getPlatform(OperatingSystem.CURRENT_OS,
                    architecture != Architecture.UNKNOWN
                            ? architecture
                            : Architecture.SYSTEM_ARCH);

            return new JavaInfo(platform, result.javaVersion, result.javaVendor);
        } catch (IOException e) {
            throw e;
        } catch (Throwable e) {
            throw new IOException(e);
        }

View on GitHub (pinned to 24702dc5a0)