flowable/flowable-engine · error · FlowableException
Not allowed to access method
Error message
Not allowed to access method ${setterName} on class ${clazz.getCanonicalName()} What it means
ReflectUtil.getSetter scans a class's methods for a setter matching the given name and value type. If the JVM SecurityManager throws SecurityException during method inspection, it throws this FlowableException naming the setter and class.
Solutions
- Grant ReflectPermission (suppressAccessChecks) in your security policy.
- Avoid targeting JDK/module-encapsulated classes; use --add-opens for module boundaries you control.
- Add a proper public setter to the target class so standard access works without privileged reflection.
- Use field injection instead of setter injection if setters are inaccessible.
- Run without a restrictive SecurityManager where the platform permits.
Example fix
// before
// class has only package-private setter
void setRecipient(String r) { ... }
// after
public void setRecipient(String r) { this.recipient = r; } Defensive patterns
Strategy: validation
Validate before calling
boolean hasSetter = java.util.Arrays.stream(clazz.getMethods())
.anyMatch(m -> m.getName().equalsIgnoreCase("set" + setterName) && m.getParameterCount() == 1);
if (!hasSetter) throw new IllegalStateException("No public setter " + setterName + " on " + clazz.getName()); Try / catch
try {
Method m = ReflectUtil.getSetter(setterName, clazz, valueType);
} catch (FlowableException e) {
LOGGER.error("Setter {} blocked on {}: {}", setterName, clazz.getName(), e.getCause());
throw new SecurityConfigurationException("Grant ReflectPermission or add a public setter", e);
} Prevention
- Always provide public setters for injected properties
- Audit SecurityManager policies before upgrading JDK or app server
- Avoid sealed/module-encapsulated classes as injection targets
- Prefer constructor/field injection when setters are restricted
When it happens
Trigger: Calling getSetter (directly or via invokeSetterOrField / Flowable field injection with setter preference) when a SecurityManager or module access rules deny reflective enumeration/access of the class's declared methods.
Common situations: Strict SecurityManager policies in application servers; reflecting into module-encapsulated or sealed classes on modern JDKs; sandboxed/agent environments restricting setAccessible-equivalent access.
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
- not allowed to access field
- not allowed to access field
- Not allowed to access method
- Could not get context class loader
- Could not load class
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/dd5e6a0d82f2709c.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/util/ReflectUtil.java:246
* Returns the setter-method for the given field name or null if no setter exists.
*/
public static Method getSetter(String fieldName, Class<?> clazz, Class<?> fieldType) {
String setterName = "set" + Character.toTitleCase(fieldName.charAt(0)) + fieldName.substring(1);
try {
// Using getMethods(), getMethod(...) expects exact parameter type
// matching and ignores inheritance-tree.
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.getName().equals(setterName)) {
Class<?>[] paramTypes = method.getParameterTypes();
if (paramTypes != null && paramTypes.length == 1 && paramTypes[0].isAssignableFrom(fieldType)) {
return method;
}
}
}
return null;
} catch (SecurityException e) {
throw new FlowableException("Not allowed to access method " + setterName + " on class " + clazz.getCanonicalName(), e);
}
}
public static void invokeSetter(Method setterMethod, Object target, String name, Object value) {
try {
setterMethod.invoke(target, value);
} catch (IllegalArgumentException e) {
throw new FlowableException("Error while invoking '" + name + "' on class " + target.getClass().getName(), e);
} catch (IllegalAccessException e) {
throw new FlowableException("Illegal access when calling '" + name + "' on class " + target.getClass().getName(), e);
} catch (InvocationTargetException e) {
throw new FlowableException("Exception while invoking '" + name + "' on class " + target.getClass().getName(), e);
}
}
private static Method findMethod(Class<? extends Object> clazz, String methodName, Object[] args) {
for (Method method : clazz.getDeclaredMethods()) {
// TODO add parameter matchingView on GitHub (pinned to d6d39ce1c6)