{"record":{"id":"f3cc495f696c518e","repo":"flowable/flowable-engine","slug":"elexception","errorCode":null,"errorMessage":"ELException","messagePattern":"ELException","errorType":"exception","errorClass":"ELException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/javax/el/BeanELResolver.java","lineNumber":160,"sourceCode":"\t\t}\n\n\t\tBeanProperty beanProperty = property(base, property);\n\t\tif (beanProperty == null) {\n\t\t\treturn null;\n\t\t}\n\t\tMethod m = beanProperty.read(base);\n\t\tif (m == null) {\n\t\t\treturn null;\n\t\t}\n\t\tcontext.setPropertyResolved(base, property);\n\t\ttry {\n\t\t\treturn invoke(m, base, (Object[]) null);\n\t\t} catch (InvocationTargetException e) {\n\t\t\tThrowable cause = e.getCause();\n\t\t\tUtil.handleThrowable(cause);\n            throw new ELException(\"Error reading '\" + property + \"' on type '\" + base.getClass().getName() + \"'\", cause);\n\t\t} catch (Exception e) {\n\t\t\tthrow new ELException(e);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void setValue(ELContext context, Object base, Object property, Object value) {\n\t\tObjects.requireNonNull(context, \"context is null\");\n\t\tif (base == null || property == null) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (readOnly) {\n\t\t\tthrow new PropertyNotWritableException(\"resolver is read-only\");\n\t\t}\n\t\tBeanProperty beanProperty = property(base, property);\n\n\t\tif (beanProperty == null) {\n\t\t\treturn;\n\t\t}","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/javax/el/BeanELResolver.java#L142-L178","documentation":"BeanELResolver.getValue throws a bare ELException (no message, cause attached) when any non-InvocationTargetException Exception occurs while reading a bean property — e.g. IllegalAccessException on an inaccessible getter.","triggerScenarios":"Evaluating ${bean.property} where the getter method exists but cannot be reflectively invoked: non-public getter class without accessible override, security manager restrictions, or generic reflective invocation failures.","commonSituations":"Package-private or private classes with public getters (reflection needs the declaring class accessible); Java module/JPMS encapsulation blocking reflective access.","solutions":["Open the `--add-opens`/module exports for the bean's package, or make the bean class public.","Add a public getter for the referenced property.","Read the ELException's cause to identify the exact reflective failure."],"exampleFix":"// before\nclass InternalBean { public String getId() {...} } // package-private class\n// after\npublic class InternalBean { public String getId() {...} }","handlingStrategy":"type-guard","validationCode":"Method m = new PropertyDescriptor(prop, bean.getClass()).getReadMethod(); if (m != null && !Modifier.isPublic(m.getDeclaringClass().getModifiers())) throw new IllegalStateException(\"declaring class not accessible\");","typeGuard":"boolean readableViaEl(Object bean, String prop) { try { PropertyDescriptor pd = new PropertyDescriptor(prop, bean.getClass()); return pd.getReadMethod() != null && Modifier.isPublic(pd.getReadMethod().getModifiers()); } catch (IntrospectionException e) { return false; } }","tryCatchPattern":"try { v = resolver.getValue(ctx, bean, prop); } catch (ELException e) { /* check cause: IllegalAccessException -> open module / make class public */ }","preventionTips":["Make bean classes and getters public","Add --add-opens when using JPMS with reflective EL access","Test EL property access against every bean in CI"],"tags":["el","bean","reflection","accessibility","expression-language"],"backgroundTag":"unsupported-operation","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"}