HMCL-dev/HMCL · error · PatchException

Failed to load JavaFX cache

Error message

Failed to load JavaFX cache

What it means

After downloading JavaFX dependencies, patch() loads them from the local cache via loadFromCache(). If that step throws IOException (unreadable/corrupt cached jars), it is rethrown as this PatchException, meaning the cached JavaFX modules could not be read back.

Solutions

  1. Delete the HMCL JavaFX cache directory and rerun so dependencies are re-downloaded
  2. Fix filesystem permissions on the cache directory/user home
  3. Exclude the cache directory from antivirus scanning
  4. Fall back to a JDK with bundled JavaFX to bypass caching entirely

Example fix

// before
# corrupt cache
rm -rf ~/.hmcl/cache/openjfx   # or HMCL's javafx cache location
java -jar HMCL.jar
// after: cache rebuilt automatically; alternatively:
/path/to/jdk-with-javafx/bin/java -jar HMCL.jar
Defensive patterns

Strategy: try-catch

Validate before calling

Path cacheDir = Path.of(System.getProperty("user.home"), ".hmcl", "openjfx-cache");
if (Files.isDirectory(cacheDir) && !Files.isReadable(cacheDir)) {
    LOG.warning("JavaFX cache unreadable; delete it and rerun");
}

Try / catch

try {
    SelfDependencyPatcher.patchIfNeeded();
} catch (PatchException e) {
    if (e.getMessage().contains("cache")) {
        // delete corrupt cache and retry once
        FileUtils.deleteDirectory(cacheDir);
        SelfDependencyPatcher.patchIfNeeded();
    }
}

Prevention

When it happens

Trigger: patch() calls loadFromCache() and it throws IOException — cache directory unreadable, cached JARs corrupted or deleted mid-read, or permission problems on the cache files.

Common situations: Corrupt cache after an interrupted download; cache files with wrong permissions; antivirus locking the cache directory; cache cleared between download and load.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

Appendix: source

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

        // Otherwise we're free to download in Java 11+
        LOG.info("Missing JavaFX dependencies, attempting to patch in missing classes");

        // Download missing dependencies
        List<DependencyDescriptor> missingDependencies = patcher.checkMissingDependencies();
        if (!missingDependencies.isEmpty()) {
            try {
                patcher.fetchDependencies(missingDependencies);
            } catch (IOException e) {
                throw new PatchException("Failed to download dependencies", e);
            }
        }

        // Add the dependencies
        try {
            patcher.loadFromCache();
        } catch (IOException ex) {
            throw new PatchException("Failed to load JavaFX cache", ex);
        } catch (ReflectiveOperationException | NoClassDefFoundError ex) {
            throw new PatchException("Failed to add dependencies to classpath!", ex);
        }
        LOG.info(" - Done!");
    }

    private Repository showChooseRepositoryDialog() {
        final JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

        for (String line : i18n("repositories.chooser").split("\n")) {
            panel.add(new JLabel(line));
        }

        final ButtonGroup buttonGroup = new ButtonGroup();

        for (Repository repository : repositories) {
            final JRadioButton button = new JRadioButton(repository.name);

View on GitHub (pinned to 24702dc5a0)