flowable/flowable-engine · error · org.activiti.engine.ActivitiException

couldn't find constructor for ${className} with args ${Array

Error message

couldn't find constructor for ${className} with args ${Arrays.asList(args)}

What it means

ReflectUtil.instantiate(className, args) throws this when no declared constructor of the loaded class matches the supplied argument list (findMatchingConstructor returned null). No cause is chained — the constructor simply wasn't found. It signals a signature mismatch between what the caller passes and what the class declares.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/util/ReflectUtil.java:232

        for (Method method : clazz.getDeclaredMethods()) {
            // TODO add parameter matching
            if (method.getName().equals(methodName)
                    && matches(method.getParameterTypes(), args)) {
                return method;
            }
        }
        Class<?> superClass = clazz.getSuperclass();
        if (superClass != null) {
            return findMethod(superClass, methodName, args);
        }
        return null;
    }

    public static Object instantiate(String className, Object[] args) {
        Class<?> clazz = loadClass(className);
        Constructor<?> constructor = findMatchingConstructor(clazz, args);
        if (constructor == null) {
            throw new ActivitiException("couldn't find constructor for " + className + " with args " + Arrays.asList(args));
        }
        try {
            return constructor.newInstance(args);
        } catch (Exception e) {
            throw new ActivitiException("couldn't find constructor for " + className + " with args " + Arrays.asList(args), e);
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private static <T> Constructor<T> findMatchingConstructor(Class<T> clazz, Object[] args) {
        for (Constructor constructor : clazz.getDeclaredConstructors()) { // cannot use <?> or <T> due to JDK 5/6 incompatibility
            if (matches(constructor.getParameterTypes(), args)) {
                return constructor;
            }
        }
        return null;
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Verify the class exposes a constructor matching the exact arg count/types
  2. Add or change the configured constructor args in your configuration
  3. Add a matching constructor to the target class
  4. Check for primitive-vs-wrapper and null ambiguity in argument matching

Example fix

// before
ReflectUtil.instantiate("com.acme.MyType", new Object[]{"cfg"}); // MyType has only MyType(String, int)
// after
ReflectUtil.instantiate("com.acme.MyType", new Object[]{"cfg", 42});
Defensive patterns

Strategy: validation

Validate before calling

// verify a matching constructor exists before instantiate
boolean matches = false;
for (Constructor<?> c : Class.forName(className).getDeclaredConstructors()) {
  if (c.getParameterCount() == args.length) { matches = true; break; }
}
if (!matches) throw new IllegalStateException("no constructor of " + className + " takes " + args.length + " args");

Type guard

boolean instantiableWith(Class<?> clazz, Object[] args) {
  for (Constructor<?> c : clazz.getDeclaredConstructors()) {
    if (c.getParameterCount() == args.length) return true;
  }
  return false;
}

Try / catch

try {
  Object o = ReflectUtil.instantiate(className, args);
} catch (ActivitiException e) {
  throw new IllegalStateException("check constructor signature of " + className, e);
}

Prevention

When it happens

Trigger: ReflectUtil.instantiate("com.example.Foo", new Object[]{"a", 1}) where Foo has no constructor accepting those argument types/count (matching is strict, incl. primitives vs wrappers).

Common situations: Configuring a custom class (e.g. variable type, session factory) with constructor args that don't fit; upgrading the library where the class's constructor changed; passing nulls that can't disambiguate the constructor.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/45cdddfeaeb87d41. Report an issue: GitHub.