HMCL-dev/HMCL · critical · IllegalArgumentException

Cannot find method 'main(String[])' in

Error message

Cannot find method 'main(String[])' in ${mainClass}

What it means

`HMCLMultiMCBootstrap.launch` throws `IllegalArgumentException("Cannot find method 'main(String[])' in " + mainClass)` after reflectively loading the configured main class and scanning its public methods: no static void method named `main` accepting exactly one `String[]` parameter exists. This bootstrap launches MultiMC/Prism instance-installed games by delegating to the real main class; without a spec-compliant `main(String[])` the launch cannot proceed (JLS 12.1.4).

Solutions

  1. Verify `mainClass` names a class with exactly `public static void main(String[] args)`; print the value logged at launch ('Main Class: ...') and check it.
  2. If the class has a non-standard entry point, invoke that class's own launcher mechanism instead of this bootstrap, or add a compliant main wrapper.
  3. Check that the modpack template's `main_class` matches the loader version actually installed (e.g. correct Forge/Fabric main class for that Minecraft version).
  4. Reinstall the version via HMCL so it writes the correct bootstrap configuration.

Example fix

// before (instance config / query)
main_class=com.example.mod.Launcher   // has only: static void main(String arg)
// after
main_class=com.example.mod.Main       // public static void main(String[] args)
// or add a wrapper in the target class:
public static void main(String[] args) { new Launcher().launch(String.join(" ", args)); }
Defensive patterns

Strategy: try-catch

Validate before calling

static void validateMainClass(String mainClass) throws Exception {
    Class<?> c = Class.forName(mainClass);
    for (Method m : c.getMethods()) {
        if ("main".equals(m.getName()) && Modifier.isStatic(m.getModifiers())
                && m.getReturnType() == void.class && m.getParameterCount() == 1
                && m.getParameterTypes()[0] == String[].class) {
            return; // OK
        }
    }
    throw new IllegalArgumentException("No public static void main(String[]) in " + mainClass);
}

Try / catch

try {
    launch(installerInfo, mainClass, args);
} catch (IllegalArgumentException e) {
    System.err.println("Bootstrap failed: " + e.getMessage());
    System.err.println("Check main_class in the instance bootstrap profile.");
    System.exit(1);
} catch (ClassNotFoundException e) {
    System.err.println("Main class not found: " + mainClass);
    System.exit(1);
}

Prevention

When it happens

Trigger: Setting the `main_class` query parameter in the bootstrap_profile_v1 URI, or the base64 `hmcl.mmc.bootstrap.main` system property, to a class that: has no `main` method at all, has `main` with a wrong signature (`main(String)` single String, non-static, returns non-void, or varargs-only non-public variants — note `getMethods()` only returns public methods), or points to a library class rather than an entry point. `Class.forName` succeeding but the shape check failing is exactly this error.

Common situations: Modpack/instance configs where `main_class` was hand-edited or generated for a different bootstrap (e.g. a class with `public static void main(String[] args)` made package-private), Fabric/Forge installer updates changing the entry-point class, or typos in the main class name pointing to an unrelated class.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at minecraft/libraries/HMCLMultiMCBootstrap/src/main/java/org/jackhuang/hmcl/HMCLMultiMCBootstrap.java:85

        System.out.println(installerInfo);
        System.out.println("Main Class: " + mainClass);
        System.out.println("GAME MAY CRASH DUE TO BUGS. TEST YOUR GAME ON OFFICIAL MMC BEFORE REPORTING BUGS TO AUTHORS.");

        Method[] methods = Class.forName(mainClass).getMethods();
        for (Method method : methods) {
            // https://docs.oracle.com/javase/specs/jls/se21/html/jls-12.html#jls-12.1.4
            if ("main".equals(method.getName()) &&
                    Modifier.isStatic(method.getModifiers()) &&
                    method.getReturnType() == void.class &&
                    method.getParameterCount() == 1 &&
                    method.getParameters()[0].getType() == String[].class
            ) {
                method.invoke(null, (Object) args);
                return;
            }
        }

        throw new IllegalArgumentException("Cannot find method 'main(String[])' in " + mainClass);
    }

    private static Map<String, String> parseQuery(String queryParameterString) {
        if (queryParameterString == null) return Collections.emptyMap();

        Map<String, String> result = new HashMap<>();

        try (Scanner scanner = new Scanner(queryParameterString)) {
            scanner.useDelimiter("&");
            while (scanner.hasNext()) {
                String[] nameValue = scanner.next().split("=");
                if (nameValue.length == 0 || nameValue.length > 2) {
                    throw new IllegalArgumentException("bad query string");
                }

                String name = decodeURL(nameValue[0]);
                String value = nameValue.length == 2 ? decodeURL(nameValue[1]) : null;
                result.put(name, value);

View on GitHub (pinned to 24702dc5a0)