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

couldn't instantiate class

Error message

couldn't instantiate class ${className}

What it means

ReflectUtil.instantiate loads a class by name and creates a new instance via newInstance(). Any failure in loading or construction (ClassNotFoundException, no public no-arg constructor, constructor throwing, abstract/interface target) is wrapped in this ActivitiException.

Solutions

  1. Verify the class name (fully qualified, correct case) and that its jar is on the runtime classpath.
  2. Ensure the class is concrete and has a public no-argument constructor.
  3. Check the wrapped cause: ClassNotFoundException vs InvocationTargetException vs InstantiationException identifies which case applies.
  4. Run the constructor manually to surface any exception thrown during instantiation.

Example fix

// before (config)
<field name="customProvider" value="com.acme.OldProvider"/>  <!-- class removed -->
// after: update to the current FQCN and provide a public no-arg constructor
<field name="customProvider" value="com.acme.NewProvider"/>
public class NewProvider { public NewProvider() {} }
Defensive patterns

Strategy: try-catch

Validate before calling

Class<?> c;
try { c = Class.forName(className); } catch (ClassNotFoundException e) { throw new IllegalStateException("Not on classpath: " + className); }
int mods = c.getModifiers();
if (Modifier.isAbstract(mods) || c.isInterface() || !Modifier.isPublic(mods)) throw new IllegalStateException("Not instantiable: " + className);
try { c.getConstructor(); } catch (NoSuchMethodException e) { throw new IllegalStateException("No public no-arg constructor: " + className); }

Try / catch

try {
    Object o = ReflectUtil.instantiate(className);
} catch (ActivitiException e) {
    if (e.getCause() instanceof ClassNotFoundException) { /* fix classpath/name */ }
    else if (e.getCause() instanceof InstantiationException) { /* abstract or interface */ }
    else if (e.getCause() instanceof InvocationTargetException) { /* constructor threw */ }
}

Prevention

When it happens

Trigger: Calling ReflectUtil.instantiate(className) where the class is absent from the classpath, is an interface/abstract class, lacks a public no-argument constructor, or its constructor throws an exception.

Common situations: Configuring custom delegate classes or handlers with class names that were renamed or moved packages; dependencies of the class missing from the runtime classpath; updating a delegate class without updating process configuration.

Related errors


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

Appendix: source

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

            // Try the current Thread context classloader
            classLoader = Thread.currentThread().getContextClassLoader();
            url = classLoader.getResource(name);
            if (url == null) {
                // Finally, try the classloader for this class
                classLoader = ReflectUtil.class.getClassLoader();
                url = classLoader.getResource(name);
            }
        }

        return url;
    }

    public static Object instantiate(String className) {
        try {
            Class<?> clazz = loadClass(className);
            return clazz.newInstance();
        } catch (Exception e) {
            throw new ActivitiException("couldn't instantiate class " + className, e);
        }
    }

    public static Object invoke(Object target, String methodName, Object[] args) {
        try {
            Class<? extends Object> clazz = target.getClass();
            Method method = findMethod(clazz, methodName, args);
            method.setAccessible(true);
            return method.invoke(target, args);
        } catch (Exception e) {
            throw new ActivitiException("couldn't invoke " + methodName + " on " + target, e);
        }
    }

    /**
     * Returns the field of the given object or null if it doesnt exist.
     */
    public static Field getField(String fieldName, Object object) {

View on GitHub (pinned to d6d39ce1c6)