Bug 44766

Summary: Tomcat's EL implementation doesn't coerce custom Number subclasses
Product: Tomcat 6 Reporter: Maksim Kaszynski <kaszynski>
Component: JasperAssignee: Tomcat Developers Mailing List <dev>
Severity: major    
Priority: P2    
Version: 6.0.14   
Target Milestone: default   
Hardware: All   
OS: All   
URL: http://jira.jboss.com/jira/browse/RF-1715
Attachments: Code cleanup for org.apache.el.* - removes attempts to compare Object classes against primitive types.

Description Maksim Kaszynski 2008-04-07 08:17:32 UTC
I have class that extends java.lang.Number, and want to use something like #{x + 1} where x is instance of my class.
But get IllegalArgumentException.

java.util.MissingResourceException: Can't find resource for bundle java.util.PropertyResourceBundle, key el.convert
	at java.util.ResourceBundle.getObject(ResourceBundle.java:325)
	at java.util.ResourceBundle.getString(ResourceBundle.java:285)
	at org.apache.el.util.MessageFactory.getArray(MessageFactory.java:67)
	at org.apache.el.util.MessageFactory.get(MessageFactory.java:47)
	at org.apache.el.lang.ELArithmetic.coerce(ELArithmetic.java:367)
	at org.apache.el.lang.ELArithmetic.add(ELArithmetic.java:237)
	at org.apache.el.parser.AstPlus.getValue(AstPlus.java:24)
	at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
	at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)

That is caused by org.apache.el.lang.ELArithmetic.coerce(Number) method that uses very strange Number type check 

public final static boolean isNumberType(final Class type) {
        return type == (java.lang.Long.class) || type == Long.TYPE || type == (java.lang.Double.class) || type == Double.TYPE || type == (java.lang.Byte.class) || type == Byte.TYPE || type == (java.lang.Short.class) || type == Short.TYPE || type == (java.lang.Integer.class) || type == Integer.TYPE || type == (java.lang.Float.class) || type == Float.TYPE || type == (java.math.BigInteger.class) || type == (java.math.BigDecimal.class);

I think this method could make use of instanceof operator so that users could provide their own Number subclasses. 

Referenced classes reside within jasper-el.jar, so I choose Jasper component.

The bug is inspired by http://jira.jboss.com/jira/browse/RF-1715
Comment 1 Mark Thomas 2008-04-08 14:23:38 UTC
I've committed a fix to trunk. The original code is a mystery to me too at the minute.

I'll propose this for 6.0.x once people on the list have had a couple of days to mull it over.
Comment 2 Konstantin Kolinko 2008-04-08 18:39:52 UTC
Created attachment 21797 [details]
Code cleanup for org.apache.el.* - removes attempts to compare Object classes against primitive types.

Code cleanup for several classes in org.apache.el.**

In those classes there are places where java.lang.Class instances are compared against classes of primitive types (such as Long.TYPE, Integer.TYPE, etc.)

In the case when those java.lang.Class instances are a result of object.getClass() call (that is, obtained from an Object), they cannot be equal to a primitive type.  In such case these comparisons are no-op, producing the value of false.

This patch removes these no-op comparisons from the code.
Comment 3 Mark Thomas 2008-04-17 10:37:36 UTC
The patch has been applied to 6.0.x and will be in 6.0.17 onwards.