HMCL-dev/HMCL · error · IOException
Missing Java version
Error message
Missing Java version
What it means
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.
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
Defensive patterns
Strategy: try-catch
Validate before calling
Properties rel = new Properties();
rel.load(Files.newInputStream(javaHome.resolve("release")));
if (rel.getProperty("JAVA_VERSION") == null) {
skipThisJavaInstallation(); // will otherwise throw
} Try / catch
try {
JavaInfo info = JavaInfo.fromReleaseFile(javaHome);
} catch (IOException e) {
markJavaUnknownVersion(javaHome); // fallback: probe `java -version`
} Prevention
- 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
When it happens
Trigger: Reading a release file that lacks the JAVA_VERSION entry entirely (empty properties, minimal jlink/custom runtime image, or a truncated/corrupted release file).
Common situations: 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.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Unknown operating system:
- Artifact name is malformed
- Bad Build-Number
- Candidates
- Cannot parse the version of
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/322984a399dfc47f.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/java/JavaInfo.java:83
String osName = properties.get("OS_NAME");
String osArch = properties.get("OS_ARCH");
String vendor = properties.get("IMPLEMENTOR");
OperatingSystem os = "".equals(osName) && "OpenJDK BSD Porting Team".equals(vendor)
? OperatingSystem.FREEBSD
: OperatingSystem.parseOSName(osName);
Architecture arch = Architecture.parseArchName(osArch);
String javaVersion = properties.get("JAVA_VERSION");
if (os == OperatingSystem.UNKNOWN)
throw new IOException("Unknown operating system: " + osName);
if (arch == Architecture.UNKNOWN)
throw new IOException("Unknown architecture: " + osArch);
if (javaVersion == null)
throw new IOException("Missing Java version");
return new JavaInfo(Platform.getPlatform(os, arch), javaVersion, vendor);
}
public static <F, E extends ArchiveEntry> JavaInfo fromArchive(ArchiveFileTree<F, E> tree) throws IOException {
if (tree.getRoot().getSubDirs().size() != 1 || !tree.getRoot().getFiles().isEmpty())
throw new IOException();
ArchiveFileTree.Dir<E> jdkRoot = tree.getRoot().getSubDirs().values().iterator().next();
E releaseEntry = jdkRoot.getFiles().get("release");
if (releaseEntry == null)
throw new IOException("Missing release file");
JavaInfo info;
try (BufferedReader reader = new BufferedReader(new InputStreamReader(tree.getInputStream(releaseEntry), StandardCharsets.UTF_8))) {
info = JavaInfo.fromReleaseFile(reader);
}
View on GitHub (pinned to 24702dc5a0)