0

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.

Community
  • 1
  • 1
brevleq
  • 2,081
  • 10
  • 53
  • 97

2 Answers2

0

The code in MyFaces is ok. The log suggest org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer cannot find the c:implementation entry in your composite component file, Since 2.1.6, some changes were done to prevent use '/' characters inside libraryName (see MYFACES-3454 for details). A web config param (org.apache.myfaces.STRICT_JSF_2_ALLOW_SLASH_LIBRARY_NAME) was added to enable the backward behavior, but note the new behavior is mentioned in a explicit way inside the spec.

If that doesn't work, please try create a simple demo app reproducing the bug and create an issue in MyFaces Issue Tracker. In that way, there are better chances that it could get solved in a future release.

UPDATE

I tried to reproduce it with the information provided without success. The problem is the call to

componente.getFacet("conteudo").getChildren().clear();

That code remove all components inside the facet, and MyFaces is smart enought to remember the components that were removed. When the view is restored, MyFaces algorithm builds the view as in the first request and then remove the components to restore the state correctly. This behavior is expected, so there is no bug in MyFaces code. Instead, I suppose the previous behavior described is a bug in Mojarra, and you should change your code to reset your input components in other way, maybe clearing the values inside the bean, or creating a method expression attribute in your composite component that can be called when cancel operation occur and clear the required input fields. There is a lot of ways to do it.

lu4242
  • 2,318
  • 1
  • 15
  • 15
  • The web config didn't helped, perhaps cause the composite component tag declaration doesn't appear to be wrong: xmlns:hrgi="http://java.sun.com/jsf/composite/hrgi". I've added new information in question. Thanks for your attention – brevleq Apr 10 '12 at 23:28
  • I've adapted "componente.getFacet("conteudo").getChildren().clear();" from the second approach you can see here: https://cwiki.apache.org/MYFACES/clear-input-components.html. Is there another way I can clear all the components of page with no problem in my composite components?? – brevleq Apr 16 '12 at 12:42
0

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>
brevleq
  • 2,081
  • 10
  • 53
  • 97