{"record":{"id":"f2f8c2b39423e4c4","repo":"flowable/flowable-engine","slug":"error-property-method-access","errorCode":null,"errorMessage":"error.property.method.access","messagePattern":"error\\.property\\.method\\.access","errorType":"exception","errorClass":"ELException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstProperty.java","lineNumber":215,"sourceCode":"\t\treturn new MethodInfo(method.getName(), method.getReturnType(), paramTypes);\n\t}\n\n\t@Override\n\tpublic Object invoke(Bindings bindings, ELContext context, Class<?> returnType, Class<?>[] paramTypes, Object[] paramValues) {\n\t\tObject base = prefix.eval(bindings, context);\n\t\tif (base == null) {\n\t\t\tthrow new PropertyNotFoundException(LocalMessages.get(\"error.property.base.null\", prefix));\n\t\t}\n\t\tObject property = getProperty(bindings, context);\n\t\tif (property == null && strict) {\n\t\t\tthrow new PropertyNotFoundException(LocalMessages.get(\"error.property.method.notfound\", \"null\", base));\n\t\t}\n\t\tString name = bindings.convert(property, String.class);\n\t\tMethod method = findMethod(name, base.getClass(), returnType, paramTypes);\n\t\ttry {\n\t\t\treturn method.invoke(base, paramValues);\n\t\t} catch (IllegalAccessException e) {\n\t\t\tthrow new ELException(LocalMessages.get(\"error.property.method.access\", name, base.getClass()), e);\n\t\t} catch (IllegalArgumentException e) {\n\t\t\tthrow new ELException(LocalMessages.get(\"error.property.method.invocation\", name, base.getClass()), e);\n\t\t} catch (InvocationTargetException e) {\n\t\t\tthrow new ELException(LocalMessages.get(\"error.property.method.invocation\", name, base.getClass()), e.getCause());\n\t\t}\n\t}\n\n\t@Override\n\tpublic AstNode getChild(int i) {\n\t\treturn i == 0 ? prefix : null;\n\t}\n}\n","sourceCodeStart":197,"sourceCodeEnd":228,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstProperty.java#L197-L228","documentation":"ELException (error.property.method.access) thrown when Method.invoke raises IllegalAccessException during expression invocation. The method was found but the reflective call is not permitted — typically because the method or its declaring class is not accessible from the caller's context.","triggerScenarios":"invoke() on ${obj.method()} where the resolved Method cannot be legally invoked reflectively (non-public class implementing a public interface, restricted module/package, SecurityManager denial).","commonSituations":"Invoking methods on non-public classes in JPMS modules without opens/exports; calling interface methods whose implementation class is package-private; sandboxed environments restricting reflection.","solutions":["Expose the implementation class publicly or invoke through a public interface type.","Add module exports/opens (module-info: exports/opens the package) if using JPMS.","Wrap the logic in a public delegate bean and call that from EL.","Remove/relax the SecurityManager restriction or grant ReflectPermission."],"exampleFix":"// before\n// module-info.java lacks: exports com.example.services;\n// after\nmodule com.example { exports com.example.services; }","handlingStrategy":"try-catch","validationCode":"Class<?> c = base.getClass();\nif (!java.lang.reflect.Modifier.isPublic(c.getModifiers())) {\n    throw new IllegalStateException(\"EL base class must be public: \" + c);\n}","typeGuard":"boolean reflectivelyCallable(Object o, String name) {\n    try {\n        return o != null && o.getClass().getMethod(name).canAccess(o);\n    } catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n    result = expr.invoke(ctx);\n} catch (jakarta.el.ELException e) {\n    if (e.getCause() instanceof IllegalAccessException) {\n        log.warn(\"EL method inaccessible: {}\", e.getMessage());\n        throw new IllegalStateException(\"expose method publicly\", e);\n    }\n    throw e;\n}","preventionTips":["Expose EL-invoked methods on public classes only","Add opens/exports in module-info for expression-used packages","Test invocations under the production SecurityManager/module config","Provide public delegate beans for internal services"],"tags":["java","reflection","accessibility","el"],"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"}