Details
Description
RendererUtils.getConvertedUIOutputValue() throws an IllegalArgumentException because it does not recognize RendererUtils.NOTHING (see stacktrace below).
Problem is the following code, taken from RendererUtils.getConvertedUIOutputValue():
public static Object getConvertedUIOutputValue(FacesContext facesContext,
UIOutput output,
Object submittedValue)
throws ConverterException {
if (submittedValue != null && !(submittedValue instanceof String)) {
if (RendererUtils.NOTHING.equals(submittedValue))
throw new IllegalArgumentException("Submitted value of type String for component : " +
getPathToComponent(output) + "expected");
}
Problem: In my case "submittedValue" is an instance of RendererUtils.NOTHING. However, this is not recognized by the above code because it was serialized.
As one can see at the declaration of RendererUtils.NOTHING, it is intentionally Serializable. Unfortunately the detection of the value works only for not-serialized values.
Possible solution: Implement RendererUtils.NOTHING.equals() to recognize serialized versions of RendererUtils.NOTHING.
Application Background (Further explanation of the context):
During "apply request values" the component gets RendererUtils.NOTHING assigned as "submittedValue". Usually the submitted value is resetted in the "process validations" phase. But in this case "process validations" is never executed because FacesContext.renderResponse() is called earlier. So, the submitted value (= RendererUtils.NOTHING) remains in the component, gets serialized. On the next round trip the component doesnt receive a "process decodes" because it is disabled, but "process validations" is called on the component, which fails with the attached stack trace.
---------
Stacktrace:
java.lang.IllegalArgumentException: Submitted value of type String for component :
expected
org.apache.myfaces.shared_impl.renderkit.RendererUtils.getConvertedUIOutputValue(RendererUtils.java:591)
org.apache.myfaces.shared_impl.renderkit.html.HtmlMenuRendererBase.getConvertedValue(HtmlMenuRendererBase.java:126)
javax.faces.component.UIInput.getConvertedValue(UIInput.java:396)
javax.faces.component.UIInput.validate(UIInput.java:350)
javax.faces.component.UIInput.processValidators(UIInput.java:184)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:627)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:627)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:627)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:627)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:627)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:627)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:627)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:627)
javax.faces.component.UIForm.processValidators(UIForm.java:73)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:627)
javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:149)
org.apache.myfaces.lifecycle.ProcessValidationsExecutor.execute(ProcessValidationsExecutor.java:32)
org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:95)
org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:70)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:139)