apache/pulsar · error · RuntimeException

Unequal number of params and paramTypes. Each param must hav

Error message

Unequal number of params and paramTypes. Each param must have a corresponding param type

What it means

The parameterized overload Reflections.createInstance(className, classLoader, params, paramTypes) requires one entry in paramTypes for each entry in params, because it looks up the constructor with getDeclaredConstructor(paramTypes). If the array lengths differ it fails fast with this RuntimeException before doing any reflection.

Source

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

            }
            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);
        } 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(paramTypes);
                meth.setAccessible(true);
                constructorCache.put(theCls, meth);
            }
            result = meth.newInstance(params);
        } catch (InstantiationException ie) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Make params.length == paramTypes.length; add the missing Class entry or remove the extra argument.
  2. Use the exact runtime classes for each argument (e.g. int.class not Integer.class unless the constructor takes Integer).
  3. Double-check conditional code that builds the two arrays so both grow together.

Example fix

// before
createInstance(name, cl, new Object[]{"s", 1}, new Class<?>[]{String.class});
// after
createInstance(name, cl, new Object[]{"s", 1}, new Class<?>[]{String.class, int.class});
Defensive patterns

Strategy: validation

Validate before calling

if (params.length != paramTypes.length)
    throw new IllegalArgumentException("params/paramTypes length mismatch: "
        + params.length + " vs " + paramTypes.length);
// optionally verify constructor matchability first:
Class<?> c = Class.forName(userClassName, true, classLoader);
c.getDeclaredConstructor(paramTypes);

Type guard

static boolean paramsMatchTypes(Object[] params, Class<?>[] paramTypes) {
    return params != null && paramTypes != null && params.length == paramTypes.length;
}

Try / catch

try { return Reflections.createInstance(name, cl, params, paramTypes); }
catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Unequal number of params"))
        throw new IllegalArgumentException("params and paramTypes must be the same length", e);
    throw e;
}

Prevention

When it happens

Trigger: Calling Reflections.createInstance(userClassName, classLoader, new Object[]{a, b}, new Class<?>[]{A.class}) — params and paramTypes arrays of different length (either direction).

Common situations: Programmatically constructing a pluggable class with constructor arguments where one array was updated but not the other; building the arrays in a loop where an argument was conditionally skipped; passing an empty paramTypes with non-empty params.

Related errors


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