apache/pulsar · error · RuntimeException

Class must be in class path

Error message

Class  must be in class path

What it means

JavaInstanceMain.createInstance() loads the user function class with Class.forName(userClassName, true, classLoader) on the function instance classloader. If the class (or a type it references during linking) cannot be found, ClassNotFoundException/NoClassDefFoundError is wrapped into RuntimeException("Class X must be in class path").

Source

Thrown at pulsar-functions/runtime-all/src/main/java/org/apache/pulsar/functions/instance/JavaInstanceMain.java:137

            method.invoke(main, args, functionInstanceClsLoader, root);
        } catch (Throwable e) {
            try {
                shutdownLogging();
            } finally {
                System.out.println("Failed to start function instance.");
                e.printStackTrace();
                Runtime.getRuntime().halt(1);
            }
        }
    }

    public static Object createInstance(String userClassName,
                                        ClassLoader classLoader) {
        Class<?> theCls;
        try {
            theCls = Class.forName(userClassName, true, classLoader);
        } catch (ClassNotFoundException | NoClassDefFoundError cnfe) {
            throw new RuntimeException("Class " + userClassName + " must be in class path", cnfe);
        }
        Object result;
        try {
            Constructor<?> meth = theCls.getDeclaredConstructor();
            meth.setAccessible(true);

            result = meth.newInstance();
        } catch (InstantiationException ie) {
            throw new RuntimeException("User class must be concrete", ie);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException("Class " + userClassName + " doesn't have such method", e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Class " + userClassName + " must have a no-arg constructor", e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException("Class " + userClassName + " constructor throws exception", e);
        }
        return result;
    }

View on GitHub (pinned to 820761864e)

Solutions

  1. Verify the fully qualified class name in the function config matches an actual class in the submitted jar (check with `jar tf app.jar | grep MyFunction`).
  2. Rebuild/re-submit the function jar ensuring the class and its dependencies are packaged (shade or bundle deps).
  3. Confirm the jar URL(s) passed to loadJar include the user jar file.
  4. Check for NoClassDefFoundError cause — a missing dependency class, not just the function class itself.

Example fix

// before (stale name after refactor)
--className com.example.OldFunctionName
// after
--className com.example.MyFunction
Defensive patterns

Strategy: validation

Validate before calling

// verify before submitting the function
Process p = new ProcessBuilder("jar", "tf", "app.jar").start();
// or in-process:
boolean found = java.util.Collections.list(loader.getResources("com/example/MyFunction.class")).size() > 0;

Type guard

boolean classLoadable(ClassLoader cl, String fcn) { try { Class.forName(fcn, false, cl); return true; } catch (Throwable t) { return false; } }

Try / catch

try { Object f = JavaInstanceMain.createInstance(className, cl); } catch (RuntimeException e) { if (e.getCause() instanceof NoClassDefFoundError) { /* missing dependency, not just the class */ } throw e; }

Prevention

When it happens

Trigger: The function's user jar was not added to the classloader passed to createInstance (jars from loadJar missing), or the configured className is wrong/renamed, or the class references a dependency that is not on the provided classpath.

Common situations: Typos or stale FQCN in the function config after refactoring; submitting a function whose jar doesn't contain the class; shaded jar that excluded a needed dependency; package rename between versions.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/824a105a53cb5714. Report an issue: GitHub.