h:selectManyCheckbox with value="#{bean.map['somekey']}" fails
----------------------------------------------------------------
Key: MYFACES-1819
URL: https://issues.apache.org/jira/browse/MYFACES-1819
Project: MyFaces Core
Issue Type: Bug
Environment: tomcat 6, windows xp
Reporter: Leonardo Uribe
On jsf 1.1, code like this (taken from tomahawk examples displayValueOnly.jsp):
bean:
public class DVOFace implements Serializable
{
/**
* serial id for serialisation versioning
*/
private static final long serialVersionUID = 1L;
private boolean attribute = true;
private Map map = new HashMap(){
/**
* serial id for serialisation versioning
*/
private static final long serialVersionUID = 1L;
public Object get(Object key){
Object held = super.get( key );
if( held != null )
return held;
if( key.toString().toLowerCase().indexOf("list")>0 )
return new ArrayList();
return null;
}
};
public boolean isAttribute() {
return attribute;
}
public void setAttribute(boolean attribute) {
this.attribute = attribute;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
}
page:
<h:selectManyCheckbox id="selectManyCheckbox"
value="#{dvoFace.map['selectManyCheckboxList']}"
<f:selectItem itemLabel="Value 1"
itemValue="1"/>
<f:selectItem itemLabel="Value 2"
itemValue="2"/>
<f:selectItem itemLabel="Value 3"
itemValue="3"/>
</h:selectManyCheckbox>
throws the following exception:
javax.faces.FacesException: Exception while calling encodeEnd on component :
{Component-Path : [Class: javax.faces.component.UIViewRoot,ViewId:
/displayValueOnly.jsp][Class: javax.faces.component.html.HtmlForm,Id:
form][Class: javax.faces.component.html.HtmlPanelGrid,Id: firstGrid]}
at
javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:559)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:250)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:246)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:246)
at
org.apache.myfaces.application.jsp.JspViewHandlerImpl.actuallyRenderView(JspViewHandlerImpl.java:423)
at
org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(JspViewHandlerImpl.java:380)
at
org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:41)
at
org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:140)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:152)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at
org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:147)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
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.valves.RequestFilterValve.process(RequestFilterValve.java:269)
at
org.apache.catalina.valves.RemoteAddrValve.invoke(RemoteAddrValve.java:81)
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: javax.faces.FacesException: Exception while calling encodeEnd on
component : {Component-Path : [Class: javax.faces.component.UIViewRoot,ViewId:
/displayValueOnly.jsp][Class: javax.faces.component.html.HtmlForm,Id:
form][Class: javax.faces.component.html.HtmlPanelGrid,Id: firstGrid][Class:
javax.faces.component.html.HtmlSelectManyCheckbox,Id: selectManyCheckbox]}
at
javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:559)
at
org.apache.myfaces.shared_impl.renderkit.RendererUtils.renderChild(RendererUtils.java:515)
at
org.apache.myfaces.shared_impl.renderkit.html.HtmlGridRendererBase.renderChildren(HtmlGridRendererBase.java:231)
at
org.apache.myfaces.shared_impl.renderkit.html.HtmlGridRendererBase.encodeEnd(HtmlGridRendererBase.java:102)
at
javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:556)
... 25 more
Caused by: java.lang.IllegalArgumentException: ValueBinding for UISelectMany :
{Component-Path : [Class: javax.faces.component.UIViewRoot,ViewId:
/displayValueOnly.jsp][Class: javax.faces.component.html.HtmlForm,Id:
form][Class: javax.faces.component.html.HtmlPanelGrid,Id: firstGrid][Class:
javax.faces.component.html.HtmlSelectManyCheckbox,Id: selectManyCheckbox]} must
be of type List or Array
at
org.apache.myfaces.shared_impl.renderkit.RendererUtils.findUISelectManyConverter(RendererUtils.java:448)
at
org.apache.myfaces.shared_impl.renderkit.html.HtmlCheckboxRendererBase.renderCheckboxList(HtmlCheckboxRendererBase.java:100)
at
org.apache.myfaces.shared_impl.renderkit.html.HtmlCheckboxRendererBase.encodeEnd(HtmlCheckboxRendererBase.java:65)
at
javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:556)
... 29 more
Since in 1.1 this works, we have to make this works on 1.2 too
The problem is in two classes:
org.apache.myfaces.shared.renderkit.RendererUtils
and
org.apache.myfaces.shared.renderkit._SharedRendererUtils
and
javax.faces.component._SharedRendererUtils
The following code (repeated on several situations):
ValueExpression expression = component.getValueExpression("value");
if (expression == null) return null;
Class valueType = expression.getType(facesContext.getELContext());
expression.getType(facesContext.getELContext()) does not return the real value
class. The doc says this:
"........Evaluates the expression relative to the provided context, and returns
the most general type that is acceptable for an object to be passed as the
value parameter in a future call to the setValue(javax.el.ELContext,
java.lang.Object) method......."
In the case it returns java.lang.Object, but it should be ArrayList. So is
preferred to do something like this:
Object value = expression.getValue(facesContext.getELContext());
valueType = (value != null) ? value.getClass() :
expression.getType(facesContext.getELContext()) ;
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.