I am trying to make two composite componenets play well together by nesting one as a child. The setup consists of a lightbox and a input both with an attribute called "Value". This works fine, until i introduce a dynamic number of inputs, and therefore have to use a ui:repeat.
bugTest.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:pw="http://java.sun.com/jsf/composite/components">
<h:head></h:head>
<h:body>
<pw:lightBox value="Header">
<h:form>
<ui:repeat var="input" value="#{BugTestBean.inputs}">
<pw:bugTestInput value="#{input}" />
</ui:repeat>
</h:form>
</pw:lightBox>
</h:body>
</html>
The ui:repeat seems to get the value attribute of the two components mixed up, and the following exception occurs.
Caused by: javax.el.PropertyNotFoundException: /resources/components/bugTestInput.xhtml @15,62 value="#{cc.attrs.value.text}": The class 'java.lang.String' does not have the property 'text'.
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:111)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIOutput.getValue(UIOutput.java:170)
at javax.faces.component.UIInput.getValue(UIInput.java:284)
at com.sun.faces.facelets.component.UIRepeat$SavedState.populate(UIRepeat.java:879)
at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:396)
at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:402)
at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:402)
at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:356)
at com.sun.faces.facelets.component.UIRepeat.setIndex(UIRepeat.java:470)
at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:586)
at com.sun.faces.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:1042)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1819)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:304)
at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:105)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:304)
at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:105)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1819)
at com.sun.faces.renderkit.html_basic.CompositeRenderer.encodeChildren(CompositeRenderer.java:78)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1819)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:447)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
at com.ocpsoft.pretty.faces.application.PrettyViewHandler.renderView(PrettyViewHandler.java:159)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
... 33 more
It seems like the value of the lightbox is being passed to the inputs.
have boiled the example down to a minimum to produce the error.
I have tried on Mojarra 2.1.26, and 2.2.4.
BugTestBean.java
@ManagedBean(name="BugTestBean")
@ViewScoped
public class BugTestBean {
private List<BugTestInput> inputs;
public BugTestBean() {
inputs = new ArrayList<BugTestInput>();
inputs.add(new BugTestInput("Test1"));
inputs.add(new BugTestInput("Test2"));
inputs.add(new BugTestInput("Test3"));
inputs.add(new BugTestInput("Test4"));
}
public List<BugTestInput> getInputs() {
return inputs;
}
}
bugTestInput.xhtml
<cc:interface>
<cc:attribute name="value" />
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<h:inputText id="input" value="#{cc.attrs.value.text}" />
</div>
</cc:implementation>
BugTestInput.java
public class BugTestInput {
private String text;
public BugTestInput(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
lightbox.xhtml
<cc:interface>
<cc:attribute name="value" />
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<h:outputText value="#{cc.attrs.value}" />
<h:panelGroup>
<cc:insertChildren />
</h:panelGroup>
</div>
</cc:implementation>
Current Solutions
Renaming the attribute value to something else on the lightbox fixes this problem.
Leaving the attribute value empty on the lightbox also works.
Not using the ui:repeat will also fix the problem, but this isn't solid.
Currently i am using 2 attributes on the lightbox and leaving the value empty when needed
<h:outputText value="#{cc.attrs.value}#{cc.attrs.title}" />
Follow up Regardless of what the attribute name is, if they are the same on both components it will fail. Is this a bug in JSF, i have searched the bug trackers and most new patch notes without result.