flowable/flowable-engine · error · MethodNotFoundException
Method not found: ${clazz}.${name}(${paramString(paramTypes)
Error message
Method not found: ${clazz}.${name}(${paramString(paramTypes)}) What it means
Flowable's EL method resolver throws MethodNotFoundException when no method on the target class matches the expression's method name and parameter types at all. It is the terminal 'nothing matched' case after findWrapper tried all candidates.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/javax/el/Util.java:261
if (bestMatch.getExactCount() == paramCount - 1) {
// Only one parameter is not an exact match - try using the
// super class
String errorMsg = "Unable to find unambiguous method: " + clazz + "." + name + "(" + paramString(paramTypes) + ")";
match = findMostSpecificWrapper(ambiguousCandidates, paramTypes, bestMatch.getAssignableCount() > 0, errorMsg);
} else {
match = null;
}
if (match == null) {
// If multiple methods have the same matching number of parameters
// the match is ambiguous so throw an exception
throw new MethodNotFoundException("Unable to find unambiguous method: " + clazz + "." + name + "(" + paramString(paramTypes) + ")");
}
}
// Handle case where no match at all was found
if (match == null) {
throw new MethodNotFoundException("Method not found: " + clazz + "." + name + "(" + paramString(paramTypes) + ")");
}
return match;
}
/*
* This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
*/
private static <T> Wrapper<T> findMostSpecificWrapper(Collection<Wrapper<T>> candidates, Class<?>[] matchingTypes, boolean elSpecific, String errorMsg) {
List<Wrapper<T>> ambiguouses = new ArrayList<>();
for (Wrapper<T> candidate : candidates) {
boolean lessSpecific = false;
Iterator<Wrapper<T>> it = ambiguouses.iterator();
while (it.hasNext()) {
int result = isMoreSpecific(candidate, it.next(), matchingTypes, elSpecific);
if (result == 1) {
it.remove();View on GitHub (pinned to d6d39ce1c6)
Solutions
- Correct the method name or parameter usage in the EL expression
- Ensure the method exists with a signature compatible with the supplied arguments
- Re-version and redeploy process definitions after changing bean APIs so old expressions are not evaluated
Example fix
// before
${orderService.calculateTotl(order)}
// after
${orderService.calculateTotal(order)} Defensive patterns
Strategy: validation
Validate before calling
boolean exists = Arrays.stream(clazz.getMethods()).anyMatch(m -> m.getName().equals(methodName));
if (!exists) throw new IllegalStateException("Method not on target class: " + clazz.getName() + "." + methodName); Try / catch
try { return Util.result(context, base, method, argTypes, args); } catch (MethodNotFoundException e) { logger.error("Check EL expression against {}: {}", clazz, e.getMessage()); throw e; } Prevention
- Keep bean API and BPMN expressions in sync; update process definitions when signatures change
- Test all expressions via deployment-time expression validation
- Use IDE search to find expression usages before renaming methods
When it happens
Trigger: Evaluating an EL method expression whose method name does not exist on the target class, or whose argument count/types match no overload; invoked from Util.result through Util.findWrapper.
Common situations: Typo in method name in a BPMN expression; method signature changed (renamed/params changed) while deployed process definitions still reference the old signature; invoking a method on the wrong bean type.
Related errors
- Cannot find method ${name} with ${params.length} parameters
- Method not found: ${clazz}.${methodName}(${paramString(param
- error.identifier.method.notamethod
- error.property.method.notfound
- Error reading '' on type ''
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/4f74b64da50c90d4.
Report an issue: GitHub.