HMCL-dev/HMCL · error · PatchException

Unsupported platform: operating system

Error message

Unsupported platform: operating system %s, architecture %s

What it means

SelfDependencyPatcher patches missing JavaFX dependencies at runtime, but only on platform combinations it has Maven artifacts for. The constructor throws PatchException when the internal dependencies map is null, meaning the current os.name/os.arch combination is not supported for JavaFX self-patching.

Solutions

  1. Install a JDK that bundles JavaFX (e.g. Liberica Full, Azul Zulu FX) so patching is unnecessary
  2. Provide JavaFX modules on the module path yourself (--module-path /lib/javafx --add-modules javafx.controls,...)
  3. Use a supported platform (x64 Windows/Linux/macOS, common arm64 builds) or check the dependency table for your arch
  4. Contribute/upstream support for your architecture by extending the dependency map

Example fix

// before
java -jar HMCL.jar  # on unsupported arch, patcher throws
// after: use a JavaFX-bundled JDK
/path/to/liberica-full-jdk/bin/java -jar HMCL.jar
// or supply JavaFX:
java --module-path javafx-sdk/lib --add-modules javafx.controls,javafx.web -jar HMCL.jar
Defensive patterns

Strategy: validation

Validate before calling

String os = System.getProperty("os.name");
String arch = System.getProperty("os.arch");
boolean supported = (os.contains("win") || os.contains("linux") || os.contains("mac"))
        && (arch.equals("amd64") || arch.equals("x86_64") || arch.equals("aarch64"));
if (!supported) {
    // require a JavaFX-bundled JDK before launching HMCL
}

Try / catch

try {
    SelfDependencyPatcher.patchIfNeeded();
} catch (PatchException e) {
    LOG.severe("JavaFX self-patching unsupported on this platform: " + e.getMessage());
    // prompt user to install a JDK with bundled JavaFX
}

Prevention

When it happens

Trigger: Launching HMCL needing JavaFX patching on an unsupported OS/architecture pair (e.g. FreeBSD, Linux on riscv64/armv7, Windows on ARM), where the static dependency table was never initialized.

Common situations: Running HMCL on niche Linux architectures, ARM single-board computers, BSD systems, or unusual JVM os.arch values like aarch64 on unsupported OSes.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/util/SelfDependencyPatcher.java:85

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toSet;
import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf;
import static org.jackhuang.hmcl.util.gson.JsonUtils.mapTypeOf;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;

// From: https://github.com/Col-E/Recaf/blob/7378b397cee664ae81b7963b0355ef8ff013c3a7/src/main/java/me/coley/recaf/util/self/SelfDependencyPatcher.java
public final class SelfDependencyPatcher {
    private final List<DependencyDescriptor> dependencies = DependencyDescriptor.readDependencies();
    private final List<Repository> repositories;
    private final Repository defaultRepository;
    private final byte[] buffer = new byte[IOUtils.DEFAULT_BUFFER_SIZE];
    private final MessageDigest digest = DigestUtils.getDigest("SHA-1");

    private SelfDependencyPatcher() throws PatchException {
        // We can only self-patch JavaFX on specific platform.
        if (dependencies == null) {
            throw new PatchException("Unsupported platform: operating system %s, architecture %s".formatted(
                    System.getProperty("os.name"), System.getProperty("os.arch")));
        }

        final String customUrl = System.getProperty("hmcl.openjfx.repo");
        if (customUrl == null) {
            if (System.getProperty("user.country", "").equalsIgnoreCase("CN")) {
                defaultRepository = Repository.TENCENTCLOUD_MIRROR;
            } else {
                defaultRepository = Repository.MAVEN_CENTRAL;
            }
            repositories = List.of(Repository.MAVEN_CENTRAL, Repository.TENCENTCLOUD_MIRROR);
        } else {
            defaultRepository = new Repository(String.format(i18n("repositories.custom"), customUrl), customUrl);
            repositories = List.of(Repository.MAVEN_CENTRAL, Repository.TENCENTCLOUD_MIRROR, defaultRepository);
        }
    }

    private static final class DependencyDescriptor {

View on GitHub (pinned to 24702dc5a0)