I'll attach a sample web application reproducing the error. Note that this error only occurs when using Tomcat 6.0.x (i.e. it works with Jetty as it uses Sun's EL RI). Moreover it doesn't matter which JSF implementation you're using to reproduce the error (I just wanted to mention that as it's definitely no bug in MyFaces even though the following stack trace shows a FacesException). The exception stack trace: javax.faces.FacesException: Exception while calling broadcast on component : {Component-Path : [Class: javax.faces.component.UIViewRoot,ViewId: /home.jsp][ Class: javax.faces.component.html.HtmlForm,Id: j_id_jsp_923754602_1][Class: javax.faces.component.html.HtmlCommandButton,Id: j_id_jsp_923754602_3]} at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:494) at javax.faces.component.UICommand.broadcast(UICommand.java:105) at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:292) at javax.faces.component.UIViewRoot.process(UIViewRoot.java:209) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:117) at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32) at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:95) at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:70) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:144) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) at java.lang.Thread.run(Thread.java:619) Caused by: org.apache.jasper.el.JspELException: /home.jsp(12,3) '#{numberBean.number}' java.lang.IllegalArgumentException: argument type mismatch at org.apache.jasper.el.JspValueExpression.setValue(JspValueExpression.java:94) at org.apache.myfaces.event.SetPropertyActionListener.processAction(SetPropertyActionListener.java:72) at javax.faces.event.ActionEvent.processListener(ActionEvent.java:48) at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:489) ... 20 more Caused by: java.lang.IllegalArgumentException: argument type mismatch at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at javax.el.BeanELResolver.setValue(BeanELResolver.java:108) at javax.el.CompositeELResolver.setValue(CompositeELResolver.java:68) at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.access$501(FacesCompositeELResolver.java:46) at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver$6.invoke(FacesCompositeELResolver.java:132) at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.invoke(FacesCompositeELResolver.java:148) at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.setValue(FacesCompositeELResolver.java:128) at org.apache.el.parser.AstValue.setValue(AstValue.java:114) at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:249) at org.apache.jasper.el.JspValueExpression.setValue(JspValueExpression.java:85) ... 23 more
Created attachment 20757 [details] Sample web application reproducing the error
Created attachment 20759 [details] Proposed patch
patch applied to trunk vote in place on 6.0.x HEAD
This has been committed to 6.0.x and will be included in 6.0.16 onwards. Thanks for the patch.
This introduced a new bug now. In 6.0.14, when you have a selecItem whose empty value is selected (value=""), and the binding datatype was Long, EL evaluation would set it to NULL. Now, its setting it to 0.
To add to my comment above: Here is my bean: MyBean { private Long number; ...//getter .. //setter .. // other methods } Here is my JSP (JSF Page rather): <h:selectOneMenu value="#{myBean.number}" required="false" converterMessage="Number value is invalid"> <f:selectItems value="#{myBean.allNumbers}"/> </h:selectOneMenu> myBean.allNumbers is implemented as follows: public List<SelectItem> getAllNumbers() { List<SelectItem> list = new ArrayList<SelectItem>(0); list.add(new SelectItem("", "--SELECT--")); // NOTE: this causes the issue list.add(new SelectItem("1", "ONE")); list.add(new SelectItem("2", "TWO")); list.add(new SelectItem("1", "THREE")); return list; } Now, when i don't select a value (ie., leave the drop down on --SELECT--) for the Number and submit the form, Tomcat 6.0.16 would set the myBean.number to 0. Until Tomcat 6.0.14, the value is NULL. Why is this important? It ends up putting 0's in the database instead of NULL's. Thanks
Note that the Expression Language specification requires this behaviour, see "1.2.1.1 Eval-expressions as value expressions": "In the case of lvalues [...] the provided value is coerced to the actual type of the property the expression points to, before that property is set." Furthermore, according to the coercion rules defined in the section "1.18.3 Coerce A to Number type N" the Expression Language implementation has to coerce both null and "" to 0. As you can see, this behaviour is not only what one would expect but also what the specification requires.
Changing back to fixed based on previous comment.
As far as this fix changes the behavior in a significant way it is a major change that will cause a lot of trouble. With this fix it is not possible to deal with 'optional' number fields. We don't no whether the user entered the value 0L or 'nothing'. All of our SearchForms where we add restrictions for not-null fields are not working any more. To use bindings for such a simple thing is as nonpractical as using String for number fields. You are right that your fix follows the JSP 2.1 specification. But even Sun's reference implementation allows null-values. To enable Tomcat < 6.0.15 and JSF 1.2 Users to update to Tomcat > 6.0.16 I would recommend to make this behavoir configurable (e.g. with an context-param) or follow the RI and allow null-values. I will provided an other patch that solves Bernhards problem but is aware of null values. It assigns the value without coercion if it is assignable and uses coerceToType instead.
Created attachment 21962 [details] Proposed patch taking care of primitive types This patch extends the original AstValue.java with care about primitive types and not assignable values. It does not take care about the JSP 2.1 specification as far as it makes Objects nullable. It follows Suns RI EL-Implementation.
That the RI has a bug and is not spec compliant is not a justification for deliberately inserting the same bug in Tomcat. That said, I am not against an enhancement that makes this configurable. Jasper can't get at the Tomcat context configuration without making Jasper dependant on Tomcat internals, something we try not do to. To be consistent with similar configuration options it could be done with a system property (see http://svn.apache.org/repos/asf/tomcat/trunk/webapps/docs/config/systemprops.xml for examples). The code would need to ensure that setting org.apache.catalina.STRICT_SERVLET_COMPLIANCE overrides the new setting that allows nulls.
Created attachment 21981 [details] Proposed patch taking care of primitive types (configurable) Configurable with VM-parameter "org.apache.catalina.STRICT_JSP_COMPLIANCE"
Created attachment 21982 [details] Proposed patch taking care of primitive types (configurable) I renamed the parameter to "org.apache.catalina.STRICT_JSP_COMPLIANCE" and had forgotten to refactor the corresponding field-name. Please feel free to rename this field / parameter if needed.
*** Bug 45040 has been marked as a duplicate of this bug. ***
Created attachment 22028 [details] Proposed patch taking care of primitive types (configurable) Fixing NullpointerException in isAssignable when assigning values to a Map (targetClass is null then).
I have applied your patch to make this optional to trunk and proposed it for 6.0.x
The patch is applied to 6.0 in r671358 (2008-06-24) and is in 6.0.17 onwards. The system property that controls this feature is org.apache.el.parser.COERCE_TO_ZERO http://svn.apache.org/viewvc?rev=671358&view=rev http://tomcat.apache.org/tomcat-6.0-doc/config/systemprops.html
Please note this feature/bug is being tracked (and hopefully fixed!) at: https://jsp-spec-public.dev.java.net/issues/show_bug.cgi?id=183