HMCL-dev/HMCL · error · IOException

Failed to find current HMCL location

Error message

Failed to find current HMCL location

What it means

getCurrentLocation resolves the path of the currently running HMCL JAR via JarUtils.thisJarPath(). If the JVM cannot determine the source JAR (null), HMCL cannot copy itself for updates or migration, so it throws this IOException.

Solutions

  1. Run HMCL from its distributed JAR (java -jar HMCL.jar)
  2. Avoid launching from an exploded classpath/IDE when invoking update or restart features
  3. Upgrade HMCL — newer JarUtils handle more launch layouts
  4. If embedding HMCL, ensure the jar is a real file on disk, not an in-memory or nested-jar resource

Example fix

// before: IDE launch, no jar path
java -cp build/classes org.jackhuang.hmcl.Main
// after
java -jar HMCL.jar
Defensive patterns

Strategy: type-guard

Validate before calling

Path jar = JarUtils.thisJarPath();
if (jar == null) {
    LOG.warning("Not running from a jar; update unavailable");
    return;
}

Type guard

boolean canSelfUpdate() {
    return JarUtils.thisJarPath() != null;
}

Try / catch

try {
    Path loc = UpdateHandler.getCurrentLocation();
} catch (IOException e) {
    LOG.warning("Cannot determine jar location: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling updateFrom, self, or performMigration while the code is not running from a JAR file the launcher can locate — e.g. running from an exploded classes directory, from memory, or an exotic classloading setup where thisJarPath() returns null.

Common situations: Launching HMCL from an IDE without a JAR; running via a custom classloader or a shaded/native wrapper; some jpackage or module-path launches where the JAR path is not discoverable.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/upgrade/UpdateHandler.java:266

        }).collect(Collectors.joining(" "));
    }

    private static Optional<Path> tryRename(Path path, String newVersion) {
        String filename = path.getFileName().toString();
        Matcher matcher = Pattern.compile("^(?<prefix>[hH][mM][cC][lL][.-])(?<version>\\d+(?:\\.\\d+)*)(?<suffix>\\.[^.]+)$").matcher(filename);
        if (matcher.find()) {
            String newFilename = matcher.group("prefix") + newVersion + matcher.group("suffix");
            if (!newFilename.equals(filename)) {
                return Optional.of(path.resolveSibling(newFilename));
            }
        }
        return Optional.empty();
    }

    private static Path getCurrentLocation() throws IOException {
        Path path = JarUtils.thisJarPath();
        if (path == null) {
            throw new IOException("Failed to find current HMCL location");
        }
        return path;
    }

    // ==== support for old versions ===
    private static void performMigration() throws IOException {
        LOG.info("Migrating from old versions");

        Path location = getParentApplicationLocation()
                .orElseThrow(() -> new IOException("Failed to get parent application location"));

        requestUpdate(getCurrentLocation(), location);
    }

    /**
     * This method must be called from the main thread.
     */
    private static boolean isNestedApplication() {

View on GitHub (pinned to 24702dc5a0)