{"record":{"id":"4c3795920db12ff9","repo":"HMCL-dev/HMCL","slug":"incompatible-platform-javaruntime-getplatform","errorCode":null,"errorMessage":"Incompatible platform: \" + javaRuntime.getPlatform()","messagePattern":"Incompatible platform: \" \\+ javaRuntime\\.getPlatform\\(\\)","errorType":"exception","errorClass":"UnsupportedPlatformException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java","lineNumber":217,"sourceCode":"        JavaInfo info = JavaInfoUtils.fromExecutable(executable);\n        return JavaRuntime.of(executable, info, false);\n    }\n\n    public static void refresh() {\n        Task.supplyAsync(() -> searchPotentialJavaExecutables(false)).whenComplete(Schedulers.javafx(), (result, exception) -> {\n            if (result != null) {\n                LATCH.await();\n                allJava = result;\n                updateAllJavaProperty(result);\n            }\n        }).start();\n    }\n\n    public static Task<JavaRuntime> getAddJavaTask(Path binary) {\n        return Task.supplyAsync(\"Get Java\", () -> JavaManager.getJava(binary))\n                .thenApplyAsync(Schedulers.javafx(), javaRuntime -> {\n                    if (!JavaManager.isCompatible(javaRuntime.getPlatform())) {\n                        throw new UnsupportedPlatformException(\"Incompatible platform: \" + javaRuntime.getPlatform());\n                    }\n\n                    String pathString = javaRuntime.getBinary().toString();\n\n                    if (!SettingsManager.isUserSettingsReadOnly()) {\n                        SettingsManager.userSettings().getDisabledJava().remove(pathString);\n                        if (SettingsManager.userSettings().getUserJava().add(pathString)) {\n                            addJava(javaRuntime);\n                        }\n                    }\n                    return javaRuntime;\n                });\n    }\n\n    public static Task<JavaRuntime> getDownloadJavaTask(DownloadProvider downloadProvider, Platform platform, GameJavaVersion gameJavaVersion) {\n        return REPOSITORY.getDownloadJavaTask(downloadProvider, platform, gameJavaVersion)\n                .thenApplyAsync(Schedulers.javafx(), java -> {\n                    addJava(java);","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java#L199-L235","documentation":"JavaManager.getAddJavaTask wraps the async 'add a Java runtime from a binary path' flow. After resolving the binary into a JavaRuntime, it checks the detected platform (OS + architecture) against the current machine via JavaManager.isCompatible. If the runtime's platform doesn't match the running OS/arch, it throws UnsupportedPlatformException with the offending platform in the message, refusing to register a Java that cannot be used here.","triggerScenarios":"Calling JavaManager.getAddJavaTask(binary) with a binary whose detected Platform differs from the current OS (e.g. platform.getOperatingSystem() != OperatingSystem.CURRENT_OS) or whose architecture is not supported on the current system (isCompatible returns false for non-current archs per the OS-specific switch).","commonSituations":"User manually points HMCL at a JRE copied from another machine/OS (Windows java.exe on Linux, x86 JRE on ARM, etc.); a portable Minecraft distribution moved across platforms; a misdetected Java binary inside a Wine/Proton prefix; symlinked binaries resolving to a foreign-arch runtime.","solutions":["Use a Java runtime built for the current operating system and architecture; delete or stop referencing the foreign binary","Re-check the binary path given to getAddJavaTask — it may resolve through a symlink to another platform's JRE","If the architecture differs but is intentional (e.g. Rosetta/Windows-on-ARM translation), verify the platform detection in JavaRuntime/Platform.getPlatform and update code to allow translated architectures","Catch UnsupportedPlatformException around the Task and surface a user-facing message asking them to pick a local Java"],"exampleFix":"// before\nTask<JavaRuntime> t = JavaManager.getAddJavaTask(Path.of(\"/opt/java/windows/bin/java.exe\"));\n// after\nPlatform p = JavaManager.getJavaExecutablePlatform(Path.of(\"/usr/lib/jvm/java-17/bin/java\"));\nif (JavaManager.isCompatible(p)) {\n    Task<JavaRuntime> t = JavaManager.getAddJavaTask(Path.of(\"/usr/lib/jvm/java-17/bin/java\"));\n}","handlingStrategy":"try-catch","validationCode":"Platform p = JavaManager.getJavaExecutablePlatform(binary);\nif (!JavaManager.isCompatible(p)) throw new IllegalArgumentException(\"Java binary is not for this OS/arch: \" + p);","typeGuard":"static boolean isLocalJava(Path binary) {\n    Platform p = JavaManager.getJavaExecutablePlatform(binary);\n    return p != null && JavaManager.isCompatible(p);\n}","tryCatchPattern":"try {\n    JavaRuntime rt = JavaManager.getAddJavaTask(binary).run().get();\n} catch (UnsupportedPlatformException e) {\n    LOGGER.warning(\"Cannot add Java: \" + e.getMessage());\n    // prompt user to choose a Java for the current OS/arch\n}","preventionTips":["Always verify the binary's platform with JavaManager.isCompatible before adding","Never copy JREs across machines of different OS/arch; download a native build","Resolve symlinks and check the real target path before adding","On ARM systems, explicitly avoid x86 builds unless running under a translation layer"],"tags":["java","platform","configuration"],"backgroundTag":"unsupported-platform","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"}