flowable/flowable-engine · error · FlowableException

Could not instantiate businessRuleTask (id:" +…

Error message

Could not instantiate businessRuleTask (id:" + businessRuleTask.getId() + ") class: " + businessRuleTask.getClassName()

What it means

createBusinessRuleTaskActivityBehavior instantiates a custom BusinessRuleTaskDelegate class given by businessRuleTask.getClassName() via reflection. Any failure in loading, constructing (no-arg constructor required), or casting throws FlowableException("Could not instantiate businessRuleTask (id:...) class:...") with the cause attached.

Solutions

  1. Verify the class name in the BPMN XML is correct and the class is on the engine classpath
  2. Ensure the class implements BusinessRuleTaskDelegate and has a public no-arg constructor
  3. Check getCause() of the exception to distinguish ClassNotFoundException vs InstantiationException/ClassCastException
  4. If no custom class is needed, remove the flowable:class attribute so the default BusinessRuleTaskActivityBehavior is used

Example fix

// before
public class MyRuleTask {
    public MyRuleTask(String config) { ... }
}
// after
public class MyRuleTask implements BusinessRuleTaskDelegate {
    public MyRuleTask() { }
    public void execute(DelegateExecution execution) { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = Class.forName(className);
if (!BusinessRuleTaskDelegate.class.isAssignableFrom(c)) throw new IllegalStateException(className + " must implement BusinessRuleTaskDelegate");
if (c.getConstructor() == null) throw new IllegalStateException(className + " needs a public no-arg constructor");

Try / catch

try {
    repositoryService.createDeployment().deploy();
} catch (FlowableException e) {
    if (e.getMessage().startsWith("Could not instantiate businessRuleTask")) {
        log.error("Check class name, no-arg constructor and BusinessRuleTaskDelegate interface. Cause:", e.getCause());
    }
}

Prevention

When it happens

Trigger: A business rule task declares flowable:class="..." whose class cannot be loaded (not on classpath, wrong name), has no public no-arg constructor, or does not implement BusinessRuleTaskDelegate.

Common situations: Typo in fully-qualified class name; class compiled against a different Flowable version; custom rule task lacking a no-arg constructor; deployment classloader not seeing the application class.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/factory/DefaultActivityBehaviorFactory.java:392

        } else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equals(serviceTask.getImplementationType())) {
            return createServiceTaskDelegateExpressionActivityBehavior(serviceTask);
        } else {
            return classDelegateFactory.create(serviceTask.getId(), DefaultBpmnHttpActivityDelegate.class.getName(),
                    createFieldDeclarations(serviceTask.getFieldExtensions()),
                    serviceTask.isTriggerable(),
                    getSkipExpressionFromServiceTask(serviceTask), serviceTask.getMapExceptions());
        }
    }

    @Override
    public ActivityBehavior createBusinessRuleTaskActivityBehavior(BusinessRuleTask businessRuleTask) {
        BusinessRuleTaskDelegate ruleActivity = null;
        if (StringUtils.isNotEmpty(businessRuleTask.getClassName())) {
            try {
                Class<?> clazz = Class.forName(businessRuleTask.getClassName());
                ruleActivity = (BusinessRuleTaskDelegate) clazz.getConstructor().newInstance();
            } catch (Exception e) {
                throw new FlowableException("Could not instantiate businessRuleTask (id:" + businessRuleTask.getId() + ") class: " +
                        businessRuleTask.getClassName(), e);
            }
        } else {
            ruleActivity = new BusinessRuleTaskActivityBehavior();
        }

        for (String ruleVariableInputObject : businessRuleTask.getInputVariables()) {
            ruleActivity.addRuleVariableInputIdExpression(expressionManager.createExpression(ruleVariableInputObject.trim()));
        }

        for (String rule : businessRuleTask.getRuleNames()) {
            ruleActivity.addRuleIdExpression(expressionManager.createExpression(rule.trim()));
        }

        ruleActivity.setExclude(businessRuleTask.isExclude());

        if (businessRuleTask.getResultVariableName() != null && businessRuleTask.getResultVariableName().length() > 0) {
            ruleActivity.setResultVariable(businessRuleTask.getResultVariableName());

View on GitHub (pinned to d6d39ce1c6)