flowable/flowable-engine · error · FlowableIllegalArgumentException
Class does not implement FlowableEventListener
Error message
Class <className> does not implement FlowableEventListener
What it means
Thrown by DelegateFlowableEventListener.getDelegateInstance as a FlowableIllegalArgumentException when the configured listener class name instantiates successfully but the resulting object does not implement FlowableEventListener. failOnException is set to true so the failure surfaces instead of being ignored.
Solutions
- Make the configured class implement org.flowable.engine.delegate.event.FlowableEventListener
- Correct the class name in the listener registration/configuration
- Check for mixed Activiti/Flowable imports causing the interface to be missing
- Add a startup smoke test that instantiates configured listeners and asserts the interface
Example fix
// before
public class MyListener implements ActivitiEventListener { ... }
// after
public class MyListener implements org.flowable.engine.delegate.event.FlowableEventListener {
public void onEvent(FlowableEvent event) { ... }
public boolean isFailOnException() { return false; }
} Defensive patterns
Strategy: type-guard
Validate before calling
Class<?> c = Class.forName(listenerClassName, true, classLoader);
if (!FlowableEventListener.class.isAssignableFrom(c)) {
throw new IllegalStateException(listenerClassName + " must implement FlowableEventListener");
} Type guard
static boolean isValidListenerClass(String className) {
try { return FlowableEventListener.class.isAssignableFrom(Class.forName(className)); }
catch (ClassNotFoundException e) { return false; }
} Try / catch
try { runtimeService.startProcessInstanceByKey(key); }
catch (FlowableIllegalArgumentException e) {
if (e.getMessage().contains("does not implement " + FlowableEventListener.class.getName())) {
log.error("Configured listener class wrong type: {}", e.getMessage());
} else throw e;
} Prevention
- Register listener classes with fully qualified names of FlowableEventListener implementations
- Validate configured listener classes in a startup integration test
- Check imports carefully when migrating from Activiti to Flowable
When it happens
Trigger: An event listener registered by class name points at a class whose newInstance/objectFactory result is not a FlowableEventListener; getDelegateInstance is called from onEvent during event dispatch.
Common situations: Wrong class name in listener configuration; class refactored to drop the FlowableEventListener interface; confusion between different listener interfaces (e.g. Activiti vs Flowable, or entity vs engine listeners) after a migration.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Delegate expression + expression + did not resolve to an…
- doesn't implement FlowableCollectionHandler
- A process instance id is required, but the provided id '" +…
- A process instance id is required, but the provided id
- activatedBefore is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/39bc0382547c9cbf.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/DelegateFlowableEventListener.java:64
@Override
public boolean isFailOnException() {
if (delegateInstance != null) {
return delegateInstance.isFailOnException();
}
return failOnException;
}
protected FlowableEventListener getDelegateInstance() {
if (delegateInstance == null) {
Object instance = ReflectUtil.instantiate(className);
if (instance instanceof FlowableEventListener) {
delegateInstance = (FlowableEventListener) instance;
} else {
// Force failing of the listener invocation, since the delegate
// cannot be created
failOnException = true;
throw new FlowableIllegalArgumentException("Class " + className + " does not implement " + FlowableEventListener.class.getName());
}
}
return delegateInstance;
}
}
View on GitHub (pinned to d6d39ce1c6)