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
- Delete the HMCL JavaFX cache directory and rerun so dependencies are re-downloaded
- Fix filesystem permissions on the cache directory/user home
- Exclude the cache directory from antivirus scanning
- 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
- Do not interrupt HMCL while it downloads JavaFX dependencies
- Keep the cache directory writable and free of antivirus locks
- Clear the cache after JVM crashes to avoid stale corrupt files
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
- Failed to load wallpaper image:
- Theme-pack asset source is not a regular file:
- Theme pack directory does not contain
- Theme pack does not contain
- Invalid theme-pack manifest
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)