flowable/flowable-engine · error · ELException
error.identifier.method.access
Error message
error.identifier.method.access
What it means
Wraps java.lang.IllegalAccessException raised while reflectively invoking the resolved static method (method.invoke(null, params)). Even though an accessible Method object was found earlier, the JVM refused the reflective call, typically due to access restrictions (module encapsulation or security manager).
Solutions
- Open/export the containing package via --add-opens/--add-exports JVM flags
- Move the target method into an exported, public package
- Make the method properly public so findAccessibleMethod returns a truly invokable Method
- Remove or relax SecurityManager restrictions if present
Example fix
// before (Java 16+, module not opened) java -jar app.jar // after java --add-opens com.myapp.internal=com.flowable app.jar
Defensive patterns
Strategy: try-catch
Validate before calling
try {
method.setAccessible(true); // fail fast with a clear AccessDeniedException before EL evaluation
} catch (RuntimeException e) {
throw new IllegalStateException("JVM denies reflective access to " + method, e);
} Try / catch
try {
methodExpr.invoke(context, params);
} catch (ELException e) {
if (e.getCause() instanceof IllegalAccessException) {
logger.error("Module/security blocked reflective access; add --add-opens for the package");
}
throw e;
} Prevention
- On Java 9+, keep delegate classes in exported packages or pass --add-opens
- Run integration tests on the same JDK as production
- Avoid invoking JDK-internal statics from EL
- Minimize SecurityManager usage or explicitly permit reflection for delegates
When it happens
Trigger: Invoking a method expression whose identifier resolved to a Method that passed findAccessibleMethod but still fails at invoke time — e.g. Java 9+ module system denying access to a non-exported package, or a SecurityManager blocking reflection.
Common situations: Running Flowable on Java 9+ with strong encapsulation where the delegate class lives in a non-exported/internal package; invoking static methods in JDK internals; app-server security policies restricting reflection.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Builder is missing constructor (can't pass features)
- Cannot find method with parameters in
- Class could not be instantiated
- Class not found
- Could not get context class loader
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/397b240a4ae679f6.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstIdentifier.java:181
}
@Override
public String getExpressionString() {
return null;
}
@Override
public int hashCode() {
return 0;
}
@Override
public boolean equals(Object obj) {
return obj == this;
}
@Override
public Object invoke(ELContext context, Object[] params) {
try {
return method.invoke(null, params);
} catch (IllegalAccessException e) {
throw new ELException(LocalMessages.get("error.identifier.method.access", name), e);
} catch (IllegalArgumentException e) {
throw new ELException(LocalMessages.get("error.identifier.method.invocation", name, e));
} catch (InvocationTargetException e) {
throw new ELException(LocalMessages.get("error.identifier.method.invocation", name, e.getCause()));
}
}
@Override
public MethodInfo getMethodInfo(ELContext context) {
return new MethodInfo(method.getName(), method.getReturnType(), method.getParameterTypes());
}
};
} else if (value instanceof MethodExpression) {
return (MethodExpression)value;
}
throw new MethodNotFoundException(LocalMessages.get("error.identifier.method.notamethod", name, value.getClass()));
}
@OverrideView on GitHub (pinned to d6d39ce1c6)