apache/pulsar · error · RuntimeException
Unequal number of params and paramTypes. Each param must…
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.
Solutions
- Make params.length == paramTypes.length; add the missing Class entry or remove the extra argument.
- Use the exact runtime classes for each argument (e.g. int.class not Integer.class unless the constructor takes Integer).
- 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
- Build params and paramTypes in the same loop so they stay in sync
- Prefer the no-arg createInstance overload when no constructor args are needed
- Unit-test reflective construction paths with representative signatures
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
- An error occurred while processing the field
- BatchSource does not implement the correct interface
- BatchSourceTriggerer does not implement the correct…
- Cannot convert from to . Conversion failed with
- Cannot convert from to . Requested converter does not…
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/6335f70a9235bdd4.
Report an issue: GitHub.
Appendix: 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)