The following snippet works fine in Tomcat 6,
<c:set var="abc" value="$12,345" />
<c:choose>
<c:when test="${abc ne 0}">
<c:out value="PASS"></c:out>
</c:when>
<c:otherwise>
<c:out value="FAIL"></c:out>
</c:otherwise>
</c:choose>
but throws exception in Tomcat 7.
javax.el.ELException: Cannot convert $1,2345 of type class java.lang.String to class java.lang.Long
at org.apache.el.lang.ELSupport.coerceToNumber(ELSupport.java:304)
at org.apache.el.lang.ELSupport.coerceToNumber(ELSupport.java:283)
at org.apache.el.lang.ELSupport.equals(ELSupport.java:143)
at org.apache.el.parser.AstNotEqual.getValue(AstNotEqual.java:40)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)
at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:1026)
at org.apache.jsp.WEB_002dINF.jsp.web.statussummary.status_005fsummary_jsp._jspx_meth_c_005fwhen_005f0(status_005fsummary_jsp.java:290)
Looks like there is a difference in the way the expression ${abc ne 0}
is evaulted in Tomcat 7. In Tomcat 6 both ${abc}
and ${0}
are compared as Strings but in Tomcat 7 I get this exception. I do not know why this should happen and which class file of which API is responsible for this.
How is this caused and how can I solve it?
This is because you are trying to compare a string to an int. Per the EL docs, section 1.8.2:
A {==,!=,eq,ne} B
■ If A==B, apply operator
■ If A is null or B is null return false for == or eq, true for != or ne.
■ If A or B is BigDecimal, coerce both A and B to BigDecimal and then:
■ If operator is == or eq, return A.equals(B)
■ If operator is != or ne, return !A.equals(B)
■ If A or B is Float or Double coerce both A and B to Double, apply operator
■ If A or B is BigInteger, coerce both A and B to BigInteger and then:
■ If operator is == or eq, return A.equals(B)
■ If operator is != or ne, return !A.equals(B)
■ If A or B is Byte, Short, Character, Integer, or Long coerce both A and B to Long, apply operator
■ If A or B is Boolean coerce both A and B to Boolean, apply operato
■ If A or B is an enum, coerce both A and B to enum, apply operatorr
■ If A or B is String coerce both A and B to String, compare lexically
■ Otherwise if an error occurs while calling A.equals(B), error
■ Otherwise, apply operator to result of A.equals(B)
The problem with your test is that you are trying to compare "$12,345"
(String) with 0
(Integer). Since 0
is an Integer, it falls into the bold If in their docs (above), where A or B is an Integer. Both are trying to be forced into a Long, which Java won't convert the String value "$12,345"
into a long. If you change your code to either of the following you will see that it works:
String comparison:
<c:set var="abc" value="$12,345" />
<c:choose>
<c:when test="${abc ne '0'}"> <!-- Change Integer to String -->
<c:out value="PASS"></c:out>
</c:when>
<c:otherwise>
<c:out value="FAIL"></c:out>
</c:otherwise>
</c:choose>
Integer comparison:
<c:set var="abc" value="12345" /> <!-- Change String to Integer -->
<c:choose>
<c:when test="${abc ne 0}">
<c:out value="PASS"></c:out>
</c:when>
<c:otherwise>
<c:out value="FAIL"></c:out>
</c:otherwise>
</c:choose>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With