Bug 55691

Summary: javax.el.ArrayELResolver.setValue not supporting arrays of primitives
Product: Tomcat 6 Reporter: taly <taly81010>
Component: Servlet & JSP APIAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 6.0.37   
Target Milestone: default   
Hardware: All   
OS: Linux   
Attachments: Proposed patch

Description taly 2013-10-22 23:05:42 UTC
was working in tomcat 6.0.20

ERROR javax.faces.context.ExceptionHandlerWrapper - javax.faces.component.UpdateModelException: java.lang.ClassCastException: Unable to add an object of type [java.lang.Integer] to an array of objects of type [int]
java.lang.ClassCastException: Unable to add an object of type [java.lang.Integer] to an array of objects of type [int]
	at javax.el.ArrayELResolver.setValue(ArrayELResolver.java:94)
	at com.sun.faces.el.DemuxCompositeELResolver._setValue(DemuxCompositeELResolver.java:255)
	at com.sun.faces.el.DemuxCompositeELResolver.setValue(DemuxCompositeELResolver.java:281)
	at org.apache.el.parser.AstValue.setValue(AstValue.java:158)
	at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:249)
	at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:131)
	at javax.faces.component.UIInput.updateModel(UIInput.java:818)
	at javax.faces.component.UIInput.processUpdates(UIInput.java:735)
	at javax.faces.component.UIData.iterate(UIData.java:2001)
	at javax.faces.component.UIData.processUpdates(UIData.java:1253)
	at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
	at javax.faces.component.UIForm.processUpdates(UIForm.java:281)
	at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
	at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
	at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1231)
	at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
Comment 1 Christopher Schultz 2013-10-23 15:42:00 UTC
Please re-try with a Tomcat 6 version that has been released in the last 4 years. 6.0.20 was released in summer 2009. Try again with Tomcat 6.0.37, which has had a bunch of fixes in the meantime. If you can reproduce with 6.0.latest, we can probably fix it.

While you're at it, please test against Tomcat 7.0.42. There are lots of differences between Tomcat 6 and 7, but much less between Tomcat 7 and 8 (where a fix is more likely to happen faster).
Comment 2 taly 2013-10-23 20:09:01 UTC
(In reply to Christopher Schultz from comment #1)
> Please re-try with a Tomcat 6 version that has been released in the last 4
> years. 6.0.20 was released in summer 2009. Try again with Tomcat 6.0.37,
> which has had a bunch of fixes in the meantime. If you can reproduce with
> 6.0.latest, we can probably fix it.
> 
> While you're at it, please test against Tomcat 7.0.42. There are lots of
> differences between Tomcat 6 and 7, but much less between Tomcat 7 and 8
> (where a fix is more likely to happen faster).

Sorry should have been more clear.
It was tested against 6.0.37
The stacktrace is from 6.0.37 not 6.0.20
6.0.20 was when it was still working

Did a quick test against 7.0.27 and getting same error no primitives support
Comment 3 taly 2013-10-23 20:34:17 UTC
Did a little more digging apparently this snippet of code was add to javax.el.ArrayELResolver.setValue()

if (value != null &&
        !base.getClass().getComponentType().isAssignableFrom(
                value.getClass())) {
    throw new ClassCastException(message(context,
            "objectNotAssignable",
            new Object[] {value.getClass().getName(),
            base.getClass().getComponentType().getName()}));
}

isAssignableFrom() does not take into account autoboxing so therefore this change is breaking setValue()
Comment 4 Christopher Schultz 2013-10-25 14:17:16 UTC
Created attachment 30970 [details]
Proposed patch

Can you run this through your tests?
Comment 5 Christopher Schultz 2013-10-25 14:17:43 UTC
This patch is against Tomcat 8 (trunk), but will likely apply cleanly to earlier versions.
Comment 6 Mark Thomas 2013-10-28 21:32:53 UTC
This has been fixed in 8.0.x and 7.0.x and will be included in 7.0.48 onwards and 8.0.0-RC6 onwards. It has also been proposed for 6.0.x.

Note that the suggested patch was not used. The Util class already contained the necessary version of isAssignableFrom(). This was used instead. I also added a test case to confirm the fix.
Comment 7 Mark Thomas 2013-10-28 21:33:25 UTC
Reduce severity to something sensible.
Comment 8 Christopher Schultz 2013-10-29 03:59:58 UTC
(In reply to Mark Thomas from comment #6)
> Note that the suggested patch was not used. The Util class already contained
> the necessary version of isAssignableFrom(). This was used instead. I also
> added a test case to confirm the fix.

Aw, I worked really hard on that ;)
Comment 9 Mark Thomas 2013-12-02 14:58:09 UTC
This has been fixed in 6.0.x and will be included in 6.0.38 onwards.