String to Long comparison throws "ELException: Cannot convert" in Tomcat 7, works in Tomcat 6

14,093

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>
Share:
14,093
Admin
Author by

Admin

Updated on June 23, 2022

Comments

  • Admin
    Admin about 2 years

    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?