{"record":{"id":"c97faee782d73c29","repo":"HMCL-dev/HMCL","slug":"failed-to-find-current-hmcl-location","errorCode":null,"errorMessage":"Failed to find current HMCL location","messagePattern":"Failed to find current HMCL location","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/java/JavaInfoUtils.java","lineNumber":47,"sourceCode":"\nimport java.io.IOException;\nimport java.nio.file.Path;\n\n/**\n * @author Glavo\n * @see <a href=\"https://github.com/Glavo/java-info\">Glavo/java-info</a>\n */\npublic final class JavaInfoUtils {\n\n    private JavaInfoUtils() {\n    }\n\n    public static @NotNull JavaInfo fromExecutable(Path executable) throws IOException {\n        assert executable.isAbsolute();\n\n        Path thisPath = JarUtils.thisJarPath();\n        if (thisPath == null) {\n            throw new IOException(\"Failed to find current HMCL location\");\n        }\n\n        try {\n            Result result = JsonUtils.GSON.fromJson(SystemUtils.run(\n                    executable.toString(),\n                    \"-classpath\",\n                    thisPath.toString(),\n                    org.glavo.info.Main.class.getName()\n            ), Result.class);\n\n            if (result == null) {\n                throw new IOException(\"Failed to get Java info from \" + executable);\n            }\n\n            if (result.javaVersion == null) {\n                throw new IOException(\"Failed to get Java version from \" + executable);\n            }\n","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaInfoUtils.java#L29-L65","documentation":"JavaInfo.fromExecutable runs the candidate java executable with the HMCL jar on the classpath to introspect it, so it needs the path of the currently running HMCL jar. When JarUtils.thisJarPath() returns null (HMCL is not running from a jar), an IOException is thrown because the introspection cannot proceed.","triggerScenarios":"Calling JavaInfo.fromExecutable(executable) while HMCL is running from an exploded class directory, an IDE, or any environment where JarUtils.thisJarPath() cannot determine the current jar location.","commonSituations":"Running HMCL from an IDE (development mode) instead of the packaged jar; running via an unpacked build; exotic classloaders where the jar path is indeterminable; running from jshell or a custom launcher.","solutions":["Run HMCL from its packaged jar rather than an exploded directory or IDE classpath","Rebuild/repackage the jar so it exists at a resolvable filesystem location","In development, substitute a stub/known JavaInfo instead of calling fromExecutable","Check JarUtils.thisJarPath() != null before calling and handle the null case gracefully"],"exampleFix":"// before\nJavaInfo info = JavaInfo.fromExecutable(executable);\n// after\nPath thisJar = JarUtils.thisJarPath();\nif (thisJar == null) {\n    JavaInfo info = queryJavaInfoDirectly(executable); // e.g. parse \"java -version\" output\n} else {\n    JavaInfo info = JavaInfo.fromExecutable(executable);\n}","handlingStrategy":"type-guard","validationCode":"if (JarUtils.thisJarPath() == null) {\n    throw new IllegalStateException(\"HMCL must run from a packaged jar for Java introspection\");\n}","typeGuard":"boolean canIntrospectJava() {\n    return JarUtils.thisJarPath() != null;\n}","tryCatchPattern":"try {\n    JavaInfo info = JavaInfo.fromExecutable(executable);\n} catch (IOException e) {\n    LOG.warning(\"Cannot introspect java: HMCL jar location unknown (running from IDE?)\", e);\n    return null;\n}","preventionTips":["Test Java-introspection flows only from the packaged jar, not the IDE","Guard callers with JarUtils.thisJarPath() != null","Provide a dev-mode stub path for JavaInfo in development environments"],"tags":["java","environment","jar-path","dev-mode"],"backgroundTag":"missing-env-var","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"}