I have a facelets page with a ui:repeat tag that outputs the rows of an HTML table and each row accepts user input. This works fines. I also have a second set of data that I output using the same page and repeater (just different data). The backing bean supporting this page is ConversationScoped.
<ui:repeat value="#{cloneBuilderBean.pageTemplate}" var="row" varStatus="status">
<tr>
<td>#{row.label}</td>
<td><h:inputText value=#{row.value}/></td>
</tr>
</ui:repeat>
The problem I have is when the user clicks an h:commandButton to “continue” to the next page. This really just redisplays the current page but the collection of the repeater has been updated to a new set of data. From my debugging, it doesn’t look like I ever even get to my action method that should fire as a result of clicking the commandButton to go to the next page. The stack trace below also doesn’t show any signs of hitting my code. Any thoughts on how to resolve this error?
javax.faces.component.UpdateModelException: java.lang.ClassCastException
at javax.faces.component.UIInput.updateModel(UIInput.java:853)
at javax.faces.component.UIInput.processUpdates(UIInput.java:735)
at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:525)
at com.sun.faces.facelets.component.UIRepeat.processUpdates(UIRepeat.java:748)
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.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassCastException
at javax.el.ArrayELResolver.setValue(ArrayELResolver.java:257)
at com.sun.faces.el.DemuxCompositeELResolver._setValue(DemuxCompositeELResolver.java:255)
at com.sun.faces.el.DemuxCompositeELResolver.setValue(DemuxCompositeELResolver.java:281)
at com.sun.el.parser.AstValue.setValue(AstValue.java:197)
at com.sun.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:286)
at org.jboss.weld.el.WeldValueExpression.setValue(WeldValueExpression.java:74)
at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:131)
at javax.faces.component.UIInput.updateModel(UIInput.java:818)
... 41 more
Update: the relevant bean code is this:
private int[] part1,part2;
private int[] currentPart; //pointer to part1 or part2
private List<SelectItem> pageTemplate;
public String openItem(String value){
conversation.begin();
//database dummy data...
pageTemplate = new ArrayList(4);
pageTemplate.add(new SelectItem("Data1"));
pageTemplate.add(new SelectItem("Data2"));
pageTemplate.add(new SelectItem("Data3"));
pageTemplate.add(new SelectItem("Data4"));
//database dummy data...
part1 = new int[4];
for(int i = 0; i < part1.length; i++){
part1[i] = i+1;
}
currentPart = part1;
return "page2";
}
public String next(){
//database dummy data...
part2 = new int[4];
for(int i = 0; i < part2.length; i++){
part2[i] = i+2;
}
currentPart = part2;
return "page2";
}
the relevant view code is:
<ui:repeat value="#{CloneBuilderBean.pageTemplate}" var="row" varStatus="status">
<tr>
<td>#{row.value}</td>
<td width="300">
<h:inputHidden id="val" value="#{CloneBuilderBean.currentPart[status.index]}" />
<p:slider for="val" step="1" style="width:90%;" minValue="0" maxValue="7" />
</td>
</tr>
</ui:repeat>
<h:commandButton value="display part 2" action="#{CloneBuilderBean.next()}"/>
I reproduced your problem. It turns out that
#{CloneBuilderBean.currentPart[status.index]}is been set with aIntegerinstead of anint. It works for me when I replaceint[]byInteger[].When I tried to reproduce your problem on Tomcat 7.0.19 instead of Glassfish 3.1.1, I got a more clear exception from its EL parser: