According to this answer: Validation Error: Value is not valid
JSF by default iterates the values in the f:selectItems to check that the selected value was actually in the list initially.
currently i have the following
<select id="selectList" size="1">
<option value="20" selected="selected">20</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
If I modify an option say 50
The mentioned validation from JSF aplies.
However if I modify the option as
<option value="">50</option>
The validation does not take places and in the end the servers ends up crashing in ContextAwareTagValueExpression.setValue when it tries to set the value of the SelectOneMenu value
This happens when the org.apache.el.parser.COERCE_TO_ZERO option is set to false, if the option is set to true, the validation takes places.
So my question is, is this normal behavior? currently i need the org.apache.el.parser.COERCE_TO_ZERO option set to false.
UPDATE:
This is on MyFaces JSF 2.1.5, Apache Tomcat 6.0.37, Java 1.7.0_21
This is the current bean:
package com.test.bean;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
@ManagedBean
@SessionScoped
public class IndexBean {
private int selectedValue;
private int saveValue;
public void updateValues(ValueChangeEvent ev){
try{
saveValue = Integer.parseInt(((HtmlSelectOneMenu) ev.getComponent()).getValue().toString());
} catch(Exception ex){
return;
}
}
public List<SelectItem> getRowsPerPage(){
List<SelectItem> rows = new ArrayList<>();
rows.add(new SelectItem(20,"20"));
rows.add(new SelectItem(50,"50"));
return rows;
}
public int getSelectedValue() {
return selectedValue;
}
public void setSelectedValue(int selectedValue) {
this.selectedValue = selectedValue;
}
}
and the xhtml page:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:body>
<f:view>
<h:form>
<h:selectOneMenu value="#{indexBean.selectedValue}" valueChangeListener="#{indexBean.updateValues}" onchange="submit();">
<f:selectItems value="#{indexBean.rowsPerPage}"></f:selectItems>
</h:selectOneMenu>
</h:form>
</f:view>
</h:body>
</html>
Initially the updateValues method would throw a nullPointerException trying to get the value of the component, hence the try catch, but that end up with the following stack
sep 10, 2014 10:01:38 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalArgumentException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.el.BeanELResolver.setValue(BeanELResolver.java:129)
at javax.el.CompositeELResolver.setValue(CompositeELResolver.java:69)
at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.setValue(FacesCompositeELResolver.java:227)
at org.apache.el.parser.AstValue.setValue(AstValue.java:158)
at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:249)
at org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression.setValue(ContextAwareTagValueExpression.java:153)
at javax.faces.component.UIInput.updateModel(UIInput.java:405)
at javax.faces.component.UIInput.processUpdates(UIInput.java:327)
at javax.faces.component.UIForm.processUpdates(UIForm.java:263)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1372)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1372)
at javax.faces.component.UIViewRoot._processUpdatesDefault(UIViewRoot.java:1338)
at javax.faces.component.UIViewRoot.access$600(UIViewRoot.java:74)
at javax.faces.component.UIViewRoot$UpdateModelPhaseProcessor.process(UIViewRoot.java:1453)
at javax.faces.component.UIViewRoot._process(UIViewRoot.java:1299)
at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:799)
at org.apache.myfaces.lifecycle.UpdateModelValuesExecutor.execute(UpdateModelValuesExecutor.java:38)
at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:170)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:197)
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:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
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:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Unknown Source)