webtier@glassfish.java.net

adding composite components dynamically

From: <webtier_at_javadesktop.org>
Date: Fri, 21 Aug 2009 12:59:24 PDT

I'm trying to add a composite component to a page dynamically.

mypage.xhtml contains this:

<h:panelGroup>
        <f:event type="postAddToView" listener="#{myBean.addTheComponents}"/>
</h:panelGroup>

MyBean.java (a managed, request scoped bean) contains this:

        public void addTheComponents(ComponentSystemEvent event) {
                FacesContext context = FacesContext.getCurrentInstance();
                Resource componentResource = context.getApplication().getResourceHandler().createResource("mycomp.xhtml", "components");
                UIComponent component = context.getApplication().createComponent(context, componentResource);
                event.getComponent().getChildren().add(component);
        }

/resources/components/mycomp.xhtml is just a very simple composite component with an h:outputText. It works correctly when referenced directly in mypage.xhtml.

When I load the page, addTheComponents is called, the componentResource.getURL() looks correct (it's jndi:/server/Jsf2Test/resources/components/mycomp.xhtml), but the newly created component seems to be incomplete. Looking at it in the debugger, it's got null for just about every attribute except parent (after the add()). Id and children are both null, which seems weird. Aside from that oddity, addTheComponents() completes without issue. However, when the view is rendered, I get an exception:

java.io.IOException: PENDING_I18N: Unable to find composite component root for composite component with id null and class javax.faces.component.UINamingContainer
        at com.sun.faces.renderkit.html_basic.CompositeRenderer.encodeChildren(CompositeRenderer.java:61)
        at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:844)
        at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:285)
        at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:106)
        at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:844)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1609)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1612)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1612)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1612)
        at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:271)
        at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:126)
        at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:124)
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:103)
        at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:311)
        at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1461)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:293)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:187)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:647)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
        at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
        at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:351)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:249)
        at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:146)
        at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:746)
        at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:655)
        at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:905)
        at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:161)
        at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:136)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:103)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:89)
        at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
        at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
        at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
        at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:619)

What do I do to dynamically add a composite component? Should I be listening for a different event and adding it there, or am I doing something else wrong?
[Message sent by forum member 'stdarg' (stdarg)]

http://forums.java.net/jive/thread.jspa?messageID=361695