flowable/flowable-engine · error · FlowableException
Illegal access when calling '${name}' on class ${target.getC
Error message
Illegal access when calling '${name}' on class ${target.getClass().getName()} What it means
Flowable wraps an IllegalAccessException thrown when the reflective setter Method.invoke() is denied access — the method is not accessible from the calling context (e.g. non-public setter in a non-accessible package/module). Flowable rethrows it as a FlowableException naming the property and target class.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/util/ReflectUtil.java:256
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 matching
if (method.getName().equals(methodName) && matches(method.getParameterTypes(), args)) {
return method;
}
}
Class<?> superClass = clazz.getSuperclass();
if (superClass != null) {
return findMethod(superClass, methodName, args);
}
return null;
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Make the setter public on the target class
- Add JVM args --add-opens <module>/<package>=ALL-UNNAMED if the class is inside a sealed JDK/library module
- Ensure the code invoking the setter resides in a package with access rights
- Remove any SecurityManager policy that forbids reflective member access
Example fix
// before
private void setHistoryLevel(String level) { ... }
// after
public void setHistoryLevel(String level) { ... } Defensive patterns
Strategy: type-guard
Validate before calling
int mods = setter.getModifiers();
if (!Modifier.isPublic(mods) || !Modifier.isPublic(setter.getDeclaringClass().getModifiers()))
throw new IllegalStateException("setter must be public"); Type guard
boolean isPublicSetter(Method m) {
return Modifier.isPublic(m.getModifiers()) && m.getName().startsWith("set");
} Try / catch
try {
ReflectUtil.invokeSetter(setter, target, name, value);
} catch (FlowableException e) {
if (e.getCause() instanceof IllegalAccessException) {
setter.setAccessible(true); // last resort, then retry
}
} Prevention
- Always declare setters public
- On Java 9+ add --add-opens for packages you reflect into
- Avoid non-public classes holding configuration setters
When it happens
Trigger: invokeSetter is called on a Method that is private, package-private, or in a module/package not opened to flowable, so Reflection cannot legally call it with setAccessible not permitted.
Common situations: Java 9+ strong encapsulation (JPMS) blocking reflective access to internal packages; custom beans with non-public setters wired into engine configuration; security manager restrictions.
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
- Illegal access when calling '<fieldName>' on class <classNam
- Illegal access when calling '%s' on class %s
- Cannot access id method/field for JPA Entity
- database update java class '${upgradestepClassName}' can't b
- TypeConverter ${clazz} could not be instantiated
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/3f3450bd594ecdf1.
Report an issue: GitHub.