Bug 47428

Summary: JSTL converts BigDecimal to Long
Product: Taglibs Reporter: void <hhfdna>
Component: Standard TaglibAssignee: Tomcat Developers Mailing List <dev>
Status: CLOSED INVALID    
Severity: normal CC: hhfdna
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Windows Server 2003   

Description void 2009-06-25 09:05:59 UTC
<c:if test="{foo==0}">
   do something
</c:if>
If foo is a BigDecimal,JSTL converts its type to Long,which means if foo is in the range [0,1), for example,0.01,it always return true! That is not correct.

I checked SUN's JSP2.0 specification,in the JSP.2.3.5.7 section. It says:
 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 operator
• 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)

According to the third rule,it seems like no problem.

but when I checked apache's implementation of JSTL, in the class  org.apache.taglibs.standard.lang.jstl.Coercions,I found apache didn't implement the third specification.so the preceding example will be processed according to this rule:
If A or B is Byte, Short, Character, Integer, or Long coerce both A and B to
Long, apply operator

that is, it will convert BigDecimal to Long!

so, is this a bug or something?

looking forward to your answering.Thanks!
Comment 1 Kris Schneider 2009-06-25 11:01:06 UTC
Maybe I missed something, but I didn't see *any* Big(Decimal|Integer) coercions in org.apache.taglibs.standard.lang.jstl.Coercions. Strange. So, I'd say it's a bug - the spec clearly states that BigDecimal coercion should take place before Long coercion.
Comment 2 void 2009-06-26 00:57:16 UTC
ok,gotcha.

Will apache fix it in the next version?

The bug exists in the latest version:jakarta-taglibs-standard-1.1.2.zip

By the way,do you know if there are other JSTL implementations besides apache's

thanks!
Comment 3 Kris Schneider 2009-06-29 07:59:19 UTC
Well, I *did* miss something. I forgot that the EL implementation is now part of the container (as of JSP 2.0, I believe), and not part of JSTL. So, I guess I'm inclined to reject the bug. Any chance you can test your code on different containers to see if your results change?

The Standard taglib code you reviewed should have been targeted at implementing the JSTL 1.0 spec (JSP 1.2), which doesn't use Big(Decimal|Integer) in its coercions for relational operators.
Comment 4 void 2009-06-29 08:42:36 UTC
(In reply to comment #3)
> Well, I *did* miss something. I forgot that the EL implementation is now part
> of the container (as of JSP 2.0, I believe), and not part of JSTL. So, I guess
> I'm inclined to reject the bug. Any chance you can test your code on different
> containers to see if your results change?
> The Standard taglib code you reviewed should have been targeted at implementing
> the JSTL 1.0 spec (JSP 1.2), which doesn't use Big(Decimal|Integer) in its
> coercions for relational operators.

We tried in Tomcat 5.0.28, and WebSphere 5. Both performed uncorrectly.
Since it is as you said,what we gonna do for now?
Is there a finnal solution for this situation?

Thanks!
Comment 5 Kris Schneider 2009-06-29 10:40:11 UTC
Maybe you can provide some more detail on exactly what you're doing. Here's a test page, coerce.jsp (webapps/ROOT):

<%@ page contentType="text/plain" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<% pageContext.setAttribute("decimal", new java.math.BigDecimal("0.01")); %>
decimal: ${decimal}
decimal == 0: ${decimal == 0}
<c:if test="${decimal == 0}">true</c:if>

TC 5.0.28
decimal: 0.01
decimal == 0: false

Notice that "true" does *not* get output.

Hang on, is this exactly what you have in your page:

<c:if test="{foo==0}">

Because it should be this:

<c:if test="${foo==0}">

This discussion should also be moved to taglibs-user<<at>>jakarta.apache.org
Comment 6 Mark Thomas 2009-08-17 01:55:50 UTC
Update assignee to Tomcat dev list
Comment 7 Henri Yandell 2009-08-20 00:47:09 UTC
Closing as lack of response.