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

  1. Make the setter public on the target class
  2. Add JVM args --add-opens <module>/<package>=ALL-UNNAMED if the class is inside a sealed JDK/library module
  3. Ensure the code invoking the setter resides in a package with access rights
  4. 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

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/3f3450bd594ecdf1. Report an issue: GitHub.