apache/flink · error · ProgramInvocationException

The class %s declares a non-public main method.

Error message

The class %s declares a non-public main method.

What it means

Thrown by callMainMethod when the located main method is static but Modifier.isPublic returns false. A non-public main method (even if static) cannot be reflectively invoked across classloader boundaries in Flink's user-code isolation model.

Source

Thrown at flink-clients/src/main/java/org/apache/flink/client/program/PackagedProgram.java:354

            mainMethod = entryClass.getMethod("main", String[].class);
        } catch (NoSuchMethodException e) {
            throw new ProgramInvocationException(
                    "The class " + entryClass.getName() + " has no main(String[]) method.");
        } catch (Throwable t) {
            throw new ProgramInvocationException(
                    "Could not look up the main(String[]) method from the class "
                            + entryClass.getName()
                            + ": "
                            + t.getMessage(),
                    t);
        }

        if (!Modifier.isStatic(mainMethod.getModifiers())) {
            throw new ProgramInvocationException(
                    "The class " + entryClass.getName() + " declares a non-static main method.");
        }
        if (!Modifier.isPublic(mainMethod.getModifiers())) {
            throw new ProgramInvocationException(
                    "The class " + entryClass.getName() + " declares a non-public main method.");
        }

        try {
            mainMethod.invoke(null, (Object) args);
        } catch (IllegalArgumentException e) {
            throw new ProgramInvocationException(
                    "Could not invoke the main method, arguments are not matching.", e);
        } catch (IllegalAccessException e) {
            throw new ProgramInvocationException(
                    "Access to the main method was denied: " + e.getMessage(), e);
        } catch (InvocationTargetException e) {
            Throwable exceptionInMethod = e.getTargetException();
            if (exceptionInMethod instanceof Error) {
                throw (Error) exceptionInMethod;
            } else if (exceptionInMethod instanceof ProgramParametrizationException) {
                throw (ProgramParametrizationException) exceptionInMethod;
            } else if (exceptionInMethod instanceof ProgramInvocationException) {

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Add the 'public' modifier: 'public static void main(String[] args)'.
  2. Rebuild and resubmit.

Example fix

// before
public class MyJob {
    static void main(String[] args) { ... } // not public
}

// after
public class MyJob {
    public static void main(String[] args) throws Exception { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

try {
    Method m = entryClass.getMethod("main", String[].class);
    if (!Modifier.isPublic(m.getModifiers())) {
        throw new IllegalArgumentException("main must be public");
    }
} catch (NoSuchMethodException e) {
    throw new IllegalArgumentException("no main(String[])", e);
}

Try / catch

try {
    packagedProgram.invokeInteractiveModeForExecution();
} catch (ProgramInvocationException pie) {
    if (pie.getMessage().contains("non-public main")) {
        // add 'public' to main and rebuild
    }
    throw pie;
}

Prevention

When it happens

Trigger: The class declares 'static void main(String[])' but without 'public' (package-private or protected).

Common situations: Omitting 'public' on main, common in internal utility classes. Flink requires public so the user-code classloader can reflectively invoke it.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/19c3a77887b0ebca. Report an issue: GitHub.