flowable/flowable-engine · error · ActivitiException

Could not instantiate businessRuleTask (id:${businessRuleTas

Error message

Could not instantiate businessRuleTask (id:${businessRuleTask.getId()}) class: ${businessRuleTask.getClassName()}

What it means

For a businessRuleTask that specifies a custom className, DefaultActivityBehaviorFactory loads the class reflectively and instantiates it as a BusinessRuleTaskDelegate. Any failure (ClassNotFoundException, instantiation errors, ClassCastException) is wrapped in this ActivitiException naming the task id and class.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/factory/DefaultActivityBehaviorFactory.java:276

        fieldDeclarations.add(exceptionMapsFieldDeclaration);

    }

    @Override
    public ShellActivityBehavior createShellActivityBehavior(ServiceTask serviceTask) {
        List<FieldDeclaration> fieldDeclarations = createFieldDeclarations(serviceTask.getFieldExtensions());
        return (ShellActivityBehavior) ClassDelegate.defaultInstantiateDelegate(ShellActivityBehavior.class, fieldDeclarations);
    }

    @Override
    public ActivityBehavior createBusinessRuleTaskActivityBehavior(BusinessRuleTask businessRuleTask) {
        BusinessRuleTaskDelegate ruleActivity = null;
        if (StringUtils.isNotEmpty(businessRuleTask.getClassName())) {
            try {
                Class<?> clazz = Class.forName(businessRuleTask.getClassName());
                ruleActivity = (BusinessRuleTaskDelegate) clazz.newInstance();
            } catch (Exception e) {
                throw new ActivitiException("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)

Solutions

  1. Verify the className is fully qualified and present on the runtime classpath
  2. Ensure the class has a public no-arg constructor and implements BusinessRuleTaskDelegate
  3. Remove the className attribute to fall back to the built-in BusinessRuleTaskActivityBehavior
  4. Check the exception cause to distinguish NotFound vs Instantiation vs Cast failures

Example fix

// before
public class MyRuleTask { private MyRuleTask() {} } // no accessible ctor
// after
public class MyRuleTask implements BusinessRuleTaskDelegate {
  public MyRuleTask() {}
  // evaluateRules()/execute implementation
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify class before deploy
try {
  Class<?> c = Class.forName("com.acme.MyRuleTask");
  c.getDeclaredConstructor().setAccessible(true);
  if (!BusinessRuleTaskDelegate.class.isAssignableFrom(c))
    throw new IllegalStateException("Must implement BusinessRuleTaskDelegate");
} catch (Exception e) { throw new IllegalStateException("businessRuleTask class invalid: " + e.getMessage()); }

Type guard

static boolean isValidBusinessRuleClass(String className) {
  try {
    Class<?> c = Class.forName(className);
    return BusinessRuleTaskDelegate.class.isAssignableFrom(c) &&
           java.lang.reflect.Modifier.isPublic(c.getModifiers());
  } catch (Throwable t) { return false; }
}

Try / catch

try {
  repositoryService.createDeployment().addClasspathResource(processXml).deploy();
} catch (ActivitiException e) {
  if (e.getMessage().startsWith("Could not instantiate businessRuleTask")) {
    log.error("bad class/ctor for task; cause:", e.getCause());
  }
}

Prevention

When it happens

Trigger: A businessRuleTask in BPMN XML declares <flowable:class>my.RuleTask</flowable:class> but the class is missing, has no public no-arg constructor, is abstract, or does not implement BusinessRuleTaskDelegate.

Common situations: Typos or refactors in the class name in XML; the rules task class lives in a jar not deployed with the app; class implements the wrong interface after an engine upgrade.

Related errors


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