flowable/flowable-engine · error · org.activiti.engine.ActivitiException

Not allowed to access method

Error message

Not allowed to access method ${setterName} on class ${clazz.getCanonicalName()}

What it means

ReflectUtil.getSetter() scans getDeclaredMethods for a setter and wraps a SecurityException in an ActivitiException when the JVM security manager denies reflective method access. It reports the setter name and class, chained to the SecurityException.

Solutions

  1. Grant accessDeclaredMembers permission in the security policy
  2. Remove or relax the SecurityManager in the runtime environment
  3. Add --add-opens for the module containing the class
  4. Verify the class/package ownership — getDeclaredMethods on foreign classes needs explicit grants

Example fix

// policy file before
// (no grant)
// after
grant {
  permission java.lang.RuntimePermission "accessDeclaredMembers";
};
Defensive patterns

Strategy: validation

Validate before calling

// ensure declared methods are reachable before getSetter
try {
  clazz.getDeclaredMethods();
} catch (SecurityException e) {
  throw new IllegalStateException("declared members of " + clazz.getName() + " are not accessible");
}

Type guard

boolean setterExists(Class<?> clazz, String setterName) {
  for (Method m : clazz.getMethods()) {
    if (m.getName().equals(setterName) && m.getParameterCount() == 1) return true;
  }
  return false;
}

Try / catch

try {
  Method setter = ReflectUtil.getSetter(clazz, setterName);
} catch (ActivitiException e) {
  logger.warn("setter lookup blocked: " + e.getCause());
  // fall back to direct field access or skip property
}

Prevention

When it happens

Trigger: ReflectUtil.getSetter(clazz, setterName) while iterating clazz.getDeclaredMethods() triggers a SecurityException — the security policy forbids access to declared members of the class.

Common situations: Running under a restrictive SecurityManager; sandboxed app servers; accessing setters in encapsulated modules under Java 9+.

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/396e39fb1ae02c32. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/util/ReflectUtil.java:209

     */
    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 ActivitiException("Not allowed to access method " + setterName + " on class " + clazz.getCanonicalName(), 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)