apache/pulsar · error · RuntimeException

User class doesn't have such method

Error message

User class doesn't have such method

What it means

In this overload, a failure to locate the no-arg constructor (NoSuchMethodException from getDeclaredConstructor()) is wrapped with the message "User class doesn't have such method" — an imprecise message, but it means the class lacks a zero-argument constructor usable for reflective instantiation.

Source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/Reflections.java:129

        Class<?> theCls;
        try {
            theCls = Class.forName(userClassName, true, classLoader);
        } catch (ClassNotFoundException | NoClassDefFoundError cnfe) {
            throw new RuntimeException("User class must be in class path", cnfe);
        }
        Object result;
        try {
            Constructor<?> meth = constructorCache.get(theCls);
            if (null == meth) {
                meth = theCls.getDeclaredConstructor();
                meth.setAccessible(true);
                constructorCache.put(theCls, meth);
            }
            result = meth.newInstance();
        } catch (InstantiationException ie) {
            throw new RuntimeException("User class must be concrete", ie);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException("User class doesn't have such method", e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("User class must have a no-arg constructor", e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException("User class constructor throws exception", e);
        }
        return result;

    }

    public static Object createInstance(String userClassName,
                                        ClassLoader classLoader, Object[] params, Class<?>[] paramTypes) {
        if (params.length != paramTypes.length) {
            throw new RuntimeException(
                    "Unequal number of params and paramTypes. Each param must have a corresponding param type");
        }
        Class<?> theCls;
        try {
            theCls = Class.forName(userClassName, true, classLoader);

View on GitHub (pinned to 820761864e)

Solutions

  1. Add a public no-arg constructor to the class
  2. Use a different instantiation path if constructor arguments are required
  3. Note the misleading message: check for missing no-arg constructor, not a missing method

Example fix

// before
public MyHandler(Config c) { }
// after
public MyHandler() { }
public MyHandler(Config c) { }
Defensive patterns

Strategy: validation

Validate before calling

// ensure a no-arg constructor exists despite the vague message this error gives
Class<?> cls = Class.forName(className, true, classLoader);
try { cls.getDeclaredConstructor(); }
catch (NoSuchMethodException e) { throw new IllegalArgumentException("No no-arg constructor: " + className); }

Type guard

boolean hasNoArgCtor(Class<?> cls) { try { cls.getDeclaredConstructor(); return true; } catch (NoSuchMethodException e) { return false; } }

Try / catch

try {
    Object o = Reflections.createInstance(className, classLoader);
} catch (RuntimeException e) {
    if (e.getMessage().equals("User class doesn't have such method")) {
        // misleading message: actually means no no-arg constructor
        throw new IllegalArgumentException("Add a no-arg constructor to " + className, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Configuring a class that only has parameterized constructors, so `getDeclaredConstructor()` (no args) throws NoSuchMethodException.

Common situations: Classes written with constructor injection; adding a parameterized constructor removed the implicit default constructor; generated classes without default constructors.

Related errors


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