{"record":{"id":"c0efc7b4abdd10b7","repo":"HMCL-dev/HMCL","slug":"failed-to-add-dependencies-to-classpath","errorCode":null,"errorMessage":"Failed to add dependencies to classpath!","messagePattern":"Failed to add dependencies to classpath!","errorType":"exception","errorClass":"PatchException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/util/SelfDependencyPatcher.java","lineNumber":192,"sourceCode":"        LOG.info(\"Missing JavaFX dependencies, attempting to patch in missing classes\");\n\n        // Download missing dependencies\n        List<DependencyDescriptor> missingDependencies = patcher.checkMissingDependencies();\n        if (!missingDependencies.isEmpty()) {\n            try {\n                patcher.fetchDependencies(missingDependencies);\n            } catch (IOException e) {\n                throw new PatchException(\"Failed to download dependencies\", e);\n            }\n        }\n\n        // Add the dependencies\n        try {\n            patcher.loadFromCache();\n        } catch (IOException ex) {\n            throw new PatchException(\"Failed to load JavaFX cache\", ex);\n        } catch (ReflectiveOperationException | NoClassDefFoundError ex) {\n            throw new PatchException(\"Failed to add dependencies to classpath!\", ex);\n        }\n        LOG.info(\" - Done!\");\n    }\n\n    private Repository showChooseRepositoryDialog() {\n        final JPanel panel = new JPanel();\n        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));\n\n        for (String line : i18n(\"repositories.chooser\").split(\"\\n\")) {\n            panel.add(new JLabel(line));\n        }\n\n        final ButtonGroup buttonGroup = new ButtonGroup();\n\n        for (Repository repository : repositories) {\n            final JRadioButton button = new JRadioButton(repository.name);\n            button.putClientProperty(\"repository\", repository);\n            buttonGroup.add(button);","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/util/SelfDependencyPatcher.java#L174-L210","documentation":"In patch(), after obtaining JavaFX dependencies, HMCL adds them to the running classpath via reflection (loadFromCache). If that reflection fails (ReflectiveOperationException) or the loaded classes are absent (NoClassDefFoundError), it throws this PatchException indicating the JavaFX modules could not be attached to the classpath.","triggerScenarios":"patch() calls loadFromCache() which throws when reflecting into the system classloader / URLClassLoader internals fails, or a loaded JavaFX class triggers NoClassDefFoundError (incomplete or mismatched JavaFX module set).","commonSituations":"Running on a JVM where URLClassLoader addURL/reflection is blocked (strong encapsulation on JDK 16+, SecurityManager); partial JavaFX download causing NoClassDefFoundError; mismatched JavaFX version versus JDK.","solutions":["Add JVM flags to open the needed modules/packages (--add-opens java.base/jdk.internal.loader=ALL-UNNAMED etc.) or downgrade to a JDK where the reflection is permitted","Use a JDK bundled with JavaFX so classpath patching never runs","Re-download to get a complete, consistent JavaFX module set (clear cache first)","Match JavaFX version to the running JDK architecture/version"],"exampleFix":"// before\njava -jar HMCL.jar  # reflection into classloader blocked on JDK 17+\n// after\njava --add-opens java.base/jdk.internal.loader=ALL-UNNAMED -jar HMCL.jar\n// or use a JavaFX-bundled JDK\n/path/to/zulu-fx-jdk/bin/java -jar HMCL.jar","handlingStrategy":"try-catch","validationCode":"// detect early whether classloader reflection will be permitted\ntry {\n    ClassLoader cl = ClassLoader.getSystemClassLoader();\n    cl.getClass().getMethod(\"addURL\", URL.class).setAccessible(true);\n} catch (ReflectiveOperationException e) {\n    LOG.warning(\"Classpath patching unavailable on this JVM; use a JavaFX-bundled JDK\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    SelfDependencyPatcher.patchIfNeeded();\n} catch (PatchException e) {\n    if (e.getMessage().contains(\"classpath\")) {\n        LOG.severe(\"Could not attach JavaFX to classpath; add --add-opens flags or switch to a JavaFX-bundled JDK\", e);\n    }\n}","preventionTips":["Launch with --add-opens java.base/jdk.internal.loader=ALL-UNNAMED on JDK 16+","Prefer JDKs with bundled JavaFX on modern JVMs","Ensure the complete JavaFX module set is downloaded (no partial cache)","Match JavaFX artifact versions to the platform"],"tags":["javafx","classpath","reflection"],"backgroundTag":"module-init-failed","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}