Most EL validation problems can have their severity customized to be one of error, warning or none. A severity of none effectively ignores the error for reporting purposes.
The table below shows each of the problems that can have severity customization and explains their effects:
Description | Example | Explanation |
---|---|---|
General Syntax Error | #{* x} | Syntax errors are a general violation of the EL language. In the example, the multiplication operator '*' expects to have two operands, but only one (x) is provided. |
Empty EL Expression | #{} | Indicates that no expression has been provided. |
Missing closing bracket on expression | #{x + 5 | Indicates that a closing '}' bracket needs to be added as in "#{x + 5}" |
Applying operator to method binding | #{bean.action * 5} | If bean.action indicates a method "action()" on bean, then it is not legal EL to treat its result as a value. In the example, multiplying action by 5 attempts treat it is as a value. |
Dotted property names should use array ([]) syntax. | #{property.name.foo} | If name.foo is the key of a value in a property bundle index on property, then the EL specification recommends (although does not require) that you instead express it as property['name.foo'] to emphasize the fact that name.foo is a key in a map as opposed to, say, a bean property. |
Variable not found | #{bean property} | If bean cannot be resolved as a variable, this problem will be flagged. Since the design time doesn't know about 100% of the variables that may be active at runtime, this may be useful to suppress occassionally to reduce false positives. |
Member not found | #{bean property} | If property cannot be resolved as a property of bean, this problem will be flagged. For example, if bean is a class with no methods getProperty/setProperty. Although it is much less likely that this validation will cause false positives, if you are using a lot of different possible sources of variables like tags, it may be useful to ignore. |
Property is intermediate | #{property.name} | The problem arises because EL allows the '.' character in key names (as in bean['x.y'], but also allows it to be used as a member operator (as in bean.property). This can cause user confusion, especially in cases like the example where property represents a map backed by a resource bundle (i.e. property file). In the case of the example, suppose there is a key for name.foo. The statement property.name may then seem meaningful, even though it has no key in the bundle and will result in either a null value or a runtime exception. |
Binary operation number coercion problems | #{5 * true} | Some binary operators (like '+', '-', '*', '/' and mod, that take two operands as in x + y), expect that both operands can be coerced to numbers before applying the operation. In the example, true is a boolean literal that does not have a legal coercion to a numeric value (although some implemenations force a coercion in C-like fashion). Such coercion errors usually cause runtime exceptions. Note that variables (i.e. bean.booleanProperty) also have the same coercion problems; it is not resticted to literals. |
Binary operation boolean coercion problems | #{myBean.integerProperty && true} | Some binary operators (like &&, ||) expect that both operands can be coerced to boolean values before applying the operation. In the case of the example, myBean.integerProperty is a bean property of type Integer. EL does allow a coercion from numeric types to booleans (although some implementations may force a C-like coercion). |
Binary operation no available coercion | #{myBean.stringArrayProperty >= myBean.booleanProperty} | When a binary operator like >= is given operands, neither of which can be meaningfully coerced to derive the type of the operands, this problem is shown. In the example, neither stringArrayProperty nor booleanProperty is a valid value comparable using the ">=" operator. |
Binary coercion of literal to number | #{'a' + 'b'} | EL sometimes allows string values to be coerced to numbers. For example #{'5' + '6'} is legal, because both '5' and '6' can be converted to numbers using Long.valueOf(). However, similar coercions are illegal if such conversions can't be made. At design time, we can only be certain of such invalid conversions if an offending value is a literal (if it is a variable, we generally won't know until runtime). In the example, we can tell for sure that neither 'a' or 'b' is convertible to a numeric type expected by the + operator. |
Unary operation number coercion problem | #{-myBean.mapProperty} | The unary minus operator expects its operand to be coerable to a numeric type before applying the operation. In the example, myBean.mapProperty is of type java.util.Map, which has no valid coercion to a number. |
Unary operation boolean coercion problem | #{!myBean.mapProperty} | The unary not operator expects its operand to be coerable to a boolean type before applying the operation. In the example, myBean.mapProperty is of type java.util.Map, which has no valid coercion to a boolean. |
Unary operation string coercion not guaranteed | #{-myBean.stringProperty} | String coercions to number as expected by unary minus, are not guaranteed depending on the value of the string. This problem flags such possible problems. |
Both operands null | #{null + null} | When both operands are null, the resulting value is constant and could be manually folded (replaced by the literal constant) to reduce code. |
Binary expression always evaluates to same value | #{x + 5 * 4} | When both arguments of a binary expression are literals, the operation can folded at design time. For example, this expression can be simplified to #{x+20}. |
Equality comparison with null always evaluates to same value | #{myBean.integerProperty == null} | EL equality and relational comparisons ('==', '!=', '>=' etc.) with null always result in the same value. Generally, inequality results in true, equality and all relational operators result in false. |
Enumeration comparison always evaluates to same value | #{myBean.coins == 'notAValue'} | Since the possible values of an enumeration (Java 5 and later) are known at compile time, we can rule out comparisons that we know will always result in the same value. In the example, notAValue is not a member of the Coins enumeration, so we know the equality can never be true. |
Unary expression always evaluates to same value | #{empty 'notEmpty'} | The unary operators have operands for which the design time can detect they will always evaluate to the same value. In the example, the empty operator always results in false if applied to a non-null, non-empty string. |
Empty operator always resolves to false on type | #{empty myBean.integerProperty} | The empty operator always evaluates to false unless its operand is a null value, empty String, or an array, Map or Collection type. |
Minus applied to null always evaluates to zero | #{-null} | Null is effectively coerced to 0 when the minus operator is applied. |
First argument short-circuits expression. | #{false && someFunc()} | EL conditional operators are "short-circuiting", meaning that if the first operand provides enough information to be sure of the result, then the second operand is not evaluated. In the example, someFunc() will never be called since the logical-AND of 'false' with any value is false. Since this can be detected at design time, this probably indicates a useless or manually foldable expression. |
Second argument always evaluates the same | #{myBean.booleanProperty && false} | This is similar to the problem above, only the expression is not short-circuited. In the example, the expression will always be false. |
Applying the dot ('.') operator with null always returns null | #{map[null]} | Using null as a member accessor will always result in null. |
Possible division by zero | #{x mod 0} | Division and modulo by 0 can result in a runtime exception. |
Possible index out of bounds | #{myBean.stringArrayProperty[-1]} | Array indices must be greater than or equal to 0 and less than the size of the array or collection (the same as Java). When the design time can determine that these contraints may be broken, it flags a warning. |
Incompatible enumeration comparision | #{myBean.coins >= myBean.colors} | Comparing two enumeration values that are not of the same enumeration type (Java 5 and later) may cause an exception at runtime. |
Method expression expected | <h:commandButton action="#{bean.property}"/> | If the EL validator has information that a tag attribute expects a method expression (method binding before JSF 1.2), then it will flag an error if the EL expression evaluates to a value expression. In the example, bean.property is a value expression resolving to a bean property on bean. |
Value expression type incompatibility | <h:inputText rendered="#{bean.foo}/> | If the EL validator has information that a tag attribute expects a certain value type, then it will flag a problem if the expression cannot be coerced to that type. In the example, bean.foo is a bean property of type beans Foo. Arbitrary class type generally cannot be coerced to booleans (rendered must be boolean). |
Value expression expected | <h:inputText value="#{bean.action}/> | If a tag attribute is known to expect a value, then an problem will be flagged if a method expression is given instead. In the example, the value attribute expects a value expression but a method expression is provided instead (note that there is not way just by looking at it that we can determine it is a method expression. We must evaluate action on bean to be sure. |
Method expression signature incompatibility | <h:commandButton action="#{bean.actionTakesArg}" | If the expected signature of a method expression is known, then the validator will compare it to the provided expression and flag a problem if it doesn't match. In this case, the action attribute expects a method that takes no arguments, but one with arguments is provided. |
Property expected to be readable but has no getter | <h:outputText value="#{bean.writeOnlyProperty}/> | If a tag attribute is known to require a readable property, but an unreadable one is provided, the validator will flag a problem. |
Property expected to be writable but has no setter | <h:inputText value="#{bean.readOnlyProperty}/> | If a tag attribute is known to require a writable property, but an read-only one is provided, the validator will flag a problem. |