Search code examples
jsf-2myfacescomposite-component

JSF 2.0 - Myfaces have problems rendering composite components


Some days ago I've changed mojarra to myfaces to solve this problem, now I'm having an strange problem rendering my composite components, they simply aren't rendered the second time I open one popup (the popup is a composite component too).

The first time, as you can see in fieldset, all is rendered ok: first open

then I click in "CANCELAR" (cancel) button, and the second time, none of my composite components, except the dialog, is rendered: second open

when I've looked at log, I found these messages:

[#|2012-04-10T15:22:00.681-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:j_id_2uz|#]
[#|2012-04-10T15:22:00.684-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:inputRazaoSocial|#]
[#|2012-04-10T15:22:00.685-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:j_id_2vi|#]
[#|2012-04-10T15:22:00.685-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:j_id_2vn|#]
[#|2012-04-10T15:22:00.686-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:j_id_2vs|#] 

as you can see, the problem is that myfaces can't find a facet in composite component... The only composite component that uses facets is hrgi:popup:

<c:interface>
    <c:attribute name="titulo" default="sem titulo" required="false"/>
    <c:attribute name="renderizar" default="false" required="false"/>
    <c:attribute name="modal" default="true" required="false"/>
    <c:attribute name="bordaConteudo" default="true" required="false"/>
    <c:facet name="cabecalho" required="false"/>
    <c:facet name="conteudo" required="true"/>
    <c:facet name="botoes" required="true"/>
</c:interface>

<c:implementation>
<h:outputStylesheet library="css" name="hrgiPopup.css" target="head"/>
<h:outputStylesheet library="css" name="clearfix.css" target="head"/>
<h:outputScript library="js" name="hrgiPopup.js" target="head"/>
<h:panelGroup layout="block" rendered="#{cc.attrs.renderizar}"
              class="hrgi-dialog-panel clearfix">
    <h:panelGroup layout="block" class="hrgi-dialog-overlay clearfix" rendered="#{cc.attrs.modal}"></h:panelGroup>
    <h:panelGroup id="popup" layout="block" class="hrgi-dialog-box clearfix">
        <h:panelGroup layout="block" class="hrgi-dialog-title clearfix">
            <h:outputText style="float:left" value="#{cc.attrs.titulo}"/>
        </h:panelGroup>
        <h:panelGroup layout="block" class="hrgi-dialog-content clearfix">
            <c:renderFacet name="cabecalho" required="false"/>
            <h:panelGroup layout="block" class="hrgi-dialog-background clearfix"
                          rendered="#{cc.attrs.bordaConteudo}">
                <c:renderFacet name="conteudo" required="true"/>
            </h:panelGroup>
            <h:panelGroup layout="block" class="clearfix" rendered="#{not cc.attrs.bordaConteudo}">
                <c:renderFacet name="conteudo" required="true"/>
            </h:panelGroup>
            <c:renderFacet name="botoes" required="true"/>
            <script type="text/javascript">
                cercarEventoTab("#{cc.clientId}:popup");
            </script>
        </h:panelGroup>
    </h:panelGroup>
</h:panelGroup>
</c:implementation>

Is this a bug of MyFaces?? Mojarra doesn't show any problem like this!

UPDATED

The problem just happens when user clicks "CANCELAR" button... The action call this code to clear the fields and close the dialog:

public void cancelar(ActionEvent evento){
    fechar();
    UIComponent componente=evento.getComponent().getParent().getParent().getParent();
    componente.getFacet("conteudo").getChildren().clear();
}

this code was adapted from the approaches you can see here. In this case, only components inside facet conteudo are recreated. Works fine, except with the my composite components.


Solution

  • I don't know why, but after I've created some class to handle exceptions, this problem disappeared...

    public class HRGIExceptionHandler extends ExceptionHandlerWrapper {
    
        private ExceptionHandler wrapped;
    
        public HRGIExceptionHandler(ExceptionHandler wrapped) {
            this.wrapped = wrapped;
        }
    
        @Override
        public ExceptionHandler getWrapped() {
            return wrapped;
        }
    
        @Override
        public void handle() throws FacesException {
            Iterator i = getUnhandledExceptionQueuedEvents().iterator();
            while (i.hasNext()) {
                ExceptionQueuedEvent event = (ExceptionQueuedEvent) i.next();
                ExceptionQueuedEventContext context = (ExceptionQueuedEventContext)event.getSource();
                Throwable t = context.getException();
                try{
                    t.printStackTrace();
                }finally{
                    i.remove();
                }
            }
            getWrapped().handle();
        }
    }
    

    and

    public class HRGIExceptionHandlerFactory extends ExceptionHandlerFactory {
    
        private ExceptionHandlerFactory parent;
    
        public HRGIExceptionHandlerFactory(ExceptionHandlerFactory parent) {
            this.parent = parent;
        }
    
        @Override
        public ExceptionHandler getExceptionHandler() {
            ExceptionHandler result = new HRGIExceptionHandler(parent.getExceptionHandler());
            return result;
        }
    }
    

    finally I've added this to faces.config:

    <factory>
        <exception-handler-factory>com.hrgi.web.erp.HRGIExceptionHandlerFactory</exception-handler-factory>
    </factory>