{"record":{"id":"57c103585afea57d","repo":"flowable/flowable-engine","slug":"unknown-method-used-in-expression-expressiontex","errorCode":null,"errorMessage":"Unknown method used in expression: ${expressionText}","messagePattern":"Unknown method used in expression: (.+?)","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/el/JuelExpression.java","lineNumber":57,"sourceCode":"\n    public JuelExpression(ValueExpression valueExpression, String expressionText) {\n        this.valueExpression = valueExpression;\n        this.expressionText = expressionText;\n    }\n\n    @Override\n    public Object getValue(VariableContainer variableContainer) {\n        ELContext elContext = Context.getProcessEngineConfiguration().getExpressionManager().getElContext((VariableScope) variableContainer);\n        try {\n            ExpressionGetInvocation invocation = new ExpressionGetInvocation(valueExpression, elContext);\n            Context.getProcessEngineConfiguration()\n                    .getDelegateInterceptor()\n                    .handleInvocation(invocation);\n            return invocation.getInvocationResult();\n        } catch (PropertyNotFoundException pnfe) {\n            throw new ActivitiException(\"Unknown property used in expression: \" + expressionText, pnfe);\n        } catch (MethodNotFoundException mnfe) {\n            throw new ActivitiException(\"Unknown method used in expression: \" + expressionText, mnfe);\n        } catch (ELException ele) {\n            throw new ActivitiException(\"Error while evaluating expression: \" + expressionText, ele);\n        } catch (Exception e) {\n            throw new ActivitiException(\"Error while evaluating expression: \" + expressionText, e);\n        }\n    }\n    \n    @Override\n    public void setValue(Object value, VariableContainer variableContainer) {\n        ELContext elContext = Context.getProcessEngineConfiguration().getExpressionManager().getElContext((VariableScope) variableContainer);\n        try {\n            ExpressionSetInvocation invocation = new ExpressionSetInvocation(valueExpression, elContext, value);\n            Context.getProcessEngineConfiguration()\n                    .getDelegateInterceptor()\n                    .handleInvocation(invocation);\n        } catch (Exception e) {\n            throw new ActivitiException(\"Error while evaluating expression: \" + expressionText, e);\n        }","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/el/JuelExpression.java#L39-L75","documentation":"JuelExpression.getValue also catches MethodNotFoundException from the EL resolver, thrown when an expression invokes a method that doesn't exist on the resolved target (e.g. ${myBean.calculateX(1)} where calculateX is absent or has an incompatible signature). The engine wraps it in this ActivitiException with the expression text.","triggerScenarios":"Evaluating a method-call expression ${bean.method(...)} during getValue where the method name or its parameter types do not match any method on the target object (including JUEL's limited type-coercion rules).","commonSituations":"Renaming a method on a delegate/bean without updating BPMN expressions, wrong number or types of arguments (EL coercion, e.g. passing a String where an int is expected), method not public, or bean of a different type than expected.","solutions":["Check that the method exists on the target bean with the exact name and is public.","Match the EL argument count and types; add overloads or convert arguments (e.g. ${bean.calc('${num}' == null ? 0 : num)}).","Update BPMN expressions after refactoring method names.","Remember JUEL has no varargs/autoboxing nuance — declare simpler signatures or do conversion inside the method."],"exampleFix":"// before: BPMN calls ${orderService.getTotl(order)} but method renamed\npublic BigDecimal getTotal(Order o) {...}\n// after: update the expression to ${orderService.getTotal(order)}","handlingStrategy":"validation","validationCode":"// Reflection pre-check that the method exists before the task runs:\nObject bean = applicationContext.getBean(\"orderService\");\nfor (java.lang.reflect.Method m : bean.getClass().getMethods()) {\n  if (m.getName().equals(\"getTotal\") && m.getParameterCount() == 1) return;\n}\nthrow new IllegalStateException(\"orderService.getTotal not found — expression will fail\");","typeGuard":null,"tryCatchPattern":"try {\n  Object v = juelExpression.getValue(container);\n} catch (ActivitiException e) {\n  if (e.getCause() instanceof MethodNotFoundException) {\n    throw new IllegalStateException(\"BPMN expression references missing method: \" + e.getMessage());\n  } else { throw e; }\n}","preventionTips":["Rename methods atomically together with BPMN XML updates (search expressions in *.bpmn files).","Keep EL-invoked bean methods public with simple, unambiguous signatures.","Write integration tests that execute every service task expression."],"tags":["expression","el","method-resolution"],"backgroundTag":"method-not-implemented","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"}