{"record":{"id":"3f3450bd594ecdf1","repo":"flowable/flowable-engine","slug":"illegal-access-when-calling-name-on-class-t","errorCode":null,"errorMessage":"Illegal access when calling '${name}' on class ${target.getClass().getName()}","messagePattern":"Illegal access when calling '(.+?)' on class (.+?)","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/util/ReflectUtil.java","lineNumber":256,"sourceCode":"                    Class<?>[] paramTypes = method.getParameterTypes();\n                    if (paramTypes != null && paramTypes.length == 1 && paramTypes[0].isAssignableFrom(fieldType)) {\n                        return method;\n                    }\n                }\n            }\n            return null;\n        } catch (SecurityException e) {\n            throw new FlowableException(\"Not allowed to access method \" + setterName + \" on class \" + clazz.getCanonicalName(), e);\n        }\n    }\n    \n    public static void invokeSetter(Method setterMethod, Object target, String name, Object value) {\n        try {\n            setterMethod.invoke(target, value);\n        } catch (IllegalArgumentException e) {\n            throw new FlowableException(\"Error while invoking '\" + name + \"' on class \" + target.getClass().getName(), e);\n        } catch (IllegalAccessException e) {\n            throw new FlowableException(\"Illegal access when calling '\" + name + \"' on class \" + target.getClass().getName(), e);\n        } catch (InvocationTargetException e) {\n            throw new FlowableException(\"Exception while invoking '\" + name + \"' on class \" + target.getClass().getName(), e);\n        }\n    }\n\n    private static Method findMethod(Class<? extends Object> clazz, String methodName, Object[] args) {\n        for (Method method : clazz.getDeclaredMethods()) {\n            // TODO add parameter matching\n            if (method.getName().equals(methodName) && matches(method.getParameterTypes(), args)) {\n                return method;\n            }\n        }\n        Class<?> superClass = clazz.getSuperclass();\n        if (superClass != null) {\n            return findMethod(superClass, methodName, args);\n        }\n        return null;\n    }","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/util/ReflectUtil.java#L238-L274","documentation":"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.","triggerScenarios":"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.","commonSituations":"Java 9+ strong encapsulation (JPMS) blocking reflective access to internal packages; custom beans with non-public setters wired into engine configuration; security manager restrictions.","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"],"exampleFix":"// before\nprivate void setHistoryLevel(String level) { ... }\n// after\npublic void setHistoryLevel(String level) { ... }","handlingStrategy":"type-guard","validationCode":"int mods = setter.getModifiers();\nif (!Modifier.isPublic(mods) || !Modifier.isPublic(setter.getDeclaringClass().getModifiers()))\n    throw new IllegalStateException(\"setter must be public\");","typeGuard":"boolean isPublicSetter(Method m) {\n    return Modifier.isPublic(m.getModifiers()) && m.getName().startsWith(\"set\");\n}","tryCatchPattern":"try {\n    ReflectUtil.invokeSetter(setter, target, name, value);\n} catch (FlowableException e) {\n    if (e.getCause() instanceof IllegalAccessException) {\n        setter.setAccessible(true); // last resort, then retry\n    }\n}","preventionTips":["Always declare setters public","On Java 9+ add --add-opens for packages you reflect into","Avoid non-public classes holding configuration setters"],"tags":["reflection","access-modifier","jpms"],"backgroundTag":"permission-denied","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}