{"record":{"id":"beac0f6aad5873f8","repo":"flowable/flowable-engine","slug":"s-doesn-t-implement-s-nor-s","errorCode":null,"errorMessage":"%s doesn't implement %s nor %s","messagePattern":"(.+?) doesn't implement (.+?) nor (.+?)","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/ClassDelegate.java","lineNumber":110,"sourceCode":"    // Execution listener\n    @Override\n    public void notify(DelegateExecution execution) {\n        if (executionListenerInstance == null) {\n            executionListenerInstance = getExecutionListenerInstance();\n        }\n        Context.getProcessEngineConfiguration()\n                .getDelegateInterceptor()\n                .handleInvocation(new ExecutionListenerInvocation(executionListenerInstance, execution));\n    }\n\n    protected ExecutionListener getExecutionListenerInstance() {\n        Object delegateInstance = instantiateDelegate(className, fieldDeclarations);\n        if (delegateInstance instanceof ExecutionListener) {\n            return (ExecutionListener) delegateInstance;\n        } else if (delegateInstance instanceof JavaDelegate) {\n            return new ServiceTaskJavaDelegateActivityBehavior((JavaDelegate) delegateInstance, skipExpression);\n        } else {\n            throw new ActivitiIllegalArgumentException(delegateInstance.getClass().getName() + \" doesn't implement \" + ExecutionListener.class + \" nor \" + JavaDelegate.class);\n        }\n    }\n\n    // Task listener\n    @Override\n    public void notify(DelegateTask delegateTask) {\n        if (taskListenerInstance == null) {\n            taskListenerInstance = getTaskListenerInstance();\n        }\n        try {\n            Context.getProcessEngineConfiguration()\n                    .getDelegateInterceptor()\n                    .handleInvocation(new TaskListenerInvocation(taskListenerInstance, delegateTask));\n        } catch (Exception e) {\n            throw new ActivitiException(\"Exception while invoking TaskListener: \" + e.getMessage(), e);\n        }\n    }\n","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/ClassDelegate.java#L92-L128","documentation":"ClassDelegate.getExecutionListenerInstance instantiates the configured delegate class and expects it to implement ExecutionListener or JavaDelegate. If the instantiated class implements neither, an ActivitiIllegalArgumentException is thrown naming the class.","triggerScenarios":"A service task or execution listener configured with class='com.example.MyDelegate' whose class implements neither ExecutionListener nor JavaDelegate, resolved during getExecutionListenerInstance at execution time.","commonSituations":"Wrong class name in the BPMN XML class attribute; refactoring removed the interface implementation; typo'd class pointing at an unrelated helper class.","solutions":["Make the delegate class implement org.activiti.engine.delegate.ExecutionListener (or JavaDelegate)","Correct the class attribute in the BPMN XML to point at the right class","Ensure the deployed class version actually implements the interface (check for stale jars)"],"exampleFix":"// before\npublic class MyDelegate {\n    public void run(DelegateExecution e) { ... }\n}\n// after\npublic class MyDelegate implements ExecutionListener {\n    public void notify(DelegateExecution e) { ... }\n}","handlingStrategy":"validation","validationCode":"Class<?> c = Class.forName(delegateClassName);\nif (!ExecutionListener.class.isAssignableFrom(c) && !JavaDelegate.class.isAssignableFrom(c)) {\n    throw new IllegalStateException(delegateClassName + \" must implement ExecutionListener or JavaDelegate\");\n}","typeGuard":"static boolean isValidExecutionDelegate(Object o) {\n    return o instanceof ExecutionListener || o instanceof JavaDelegate;\n}","tryCatchPattern":"try {\n    runtimeService.signal(executionId);\n} catch (org.activiti.engine.ActivitiIllegalArgumentException e) {\n    if (e.getMessage().contains(\"doesn't implement\")) {\n        // fix the delegate class in the service task definition\n    }\n}","preventionTips":["Assert delegate classes implement the right interface in unit tests","Keep the class attribute consistent with the actual class hierarchy","Avoid refactoring away interface implementations used by BPMN configs"],"tags":["classdelegate","listener","type-mismatch","configuration"],"backgroundTag":"incompatible-source-type","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}