Search code examples
richfacescustom-error-pagesgateinviewrenderingportletbridge

Richfaces error page redirection with gatein, jboss 5.1.0 ga portlet bridge jars and my mistakes


i know there are a lot of similar questions out there about the same/similar topics but i could not apply any of the solutions to my problem.

I want to redirect user to a custom error page whenever an exception caught while rendering the portlet page. why exception thrown while rendering the page ? Its because in the background we throw it to give user some useful information, designed that way and not going to be changed anytime soon, so my intention is to keep it that way.

I belive it would be better if i give examples: This is simple portlet that i provide use name and press ">>" button to get some information about that user, in the previous implementation its working fine see the second picture..

enter image description here

Second picture:

as you can see layout is correct""(this is how it looked) the error page has simply replaced the portlet content with its own content and the error message that why we could not get any information about the user. So far so good.

enter image description here

Now lets look at the problem case: We have upgraded from jboss 4.2.3 ga to 5.1.0 ga and now GateIn comes into play ground. Also there were old jars used to create this view of portlets, now they are all upgraded to newer ones. Such as:

(org.richfaces.framework) Richfaces-api 3.3.3-final, 
(org.richfaces.framework) Richfaces-impl 3.3.3-final,
(org.richfaces.framework) Richfaces-ui 3.3.3-final,
(com.sun.faces) jsf-api 2.2.14,
(com.sun.faces) jsf-impl 2.2.14,
(javax-servlet) servlet-api 2.5,
(javax-servlet) jstl 1.2

Gatein version: 3.4

and gatein itself uses jsr168 compatible jars + we have jsf 1.2 version (tags are used in this version).

Problem case: as you can see the the portlet we want to get some user information is broken and merged into domain detailed portlet. which looks like a soup.

The code that generates this mess is also belongs to us. which was working correctly once, however its now somehow destroying the whole layout.

enter image description here

Let me show you the code that is rendering the views:

    public void renderView(FacesContext context, UIViewRoot viewToRender) throws java.io.IOException, javax.faces.FacesException{
    try {
        super.renderView(context, viewToRender);
    }catch(FacesException e){         

        Application application = context.getApplication();
        ViewHandler viewhandler = application.getViewHandler();
        PortletRequest request = (PortletRequest)context.getExternalContext().getRequest();
        PortletConfig config = (PortletConfig)request.getAttribute(PortletConstants.PORTLET_CONFIG);
        String errorView = config.getInitParameter(PortletConstants.PORTLET_FACES_ERROR_VIEW);

        if(errorView == null || errorView.matches("")){
            errorView = ProvPortletViewHandler.DEFAULT_FACES_ERROR_VIEW;                       
        }

        Throwable cause = e.getCause();
        FacesMessage fm= findProvisioningException(cause);
        if(fm == null)
        {             
            request.setAttribute("ErrorMessage", "Unknown Error occured");
        }
        else
        {
            request.setAttribute("ErrorMessage", fm.getSummary());
        } 

        viewToRender = viewhandler.createView(context,errorView);         
        context.setViewRoot(viewToRender);             
        viewhandler.renderView(context, viewToRender);

        PortletSession objSes = (PortletSession)context.getExternalContext().getSession(false);
        objSes.invalidate();
    }
}

In this piece of code, you can see that there is super.renderView(context, viewToRender);

It goes all the way to the services and makes the service call. service calls returns an exception that this user has not information in DB. and this exception is converted into FacesException on the road (we are doing it).

The problem is not the exception its nor converting it to a FacesException.

The problem occurs in this part

 viewToRender = viewhandler.createView(context,errorView);         
 context.setViewRoot(viewToRender);             
 viewhandler.renderView(context, viewToRender);

as far as we debugged. We belive somehow the old view which was partially rendered due to exception cannot be replaced with the error view.

But what could do that if it was working previously. we have not changed this part of the code.

Is this information enough to throw an idea about the problem ? Would you guys need for more details ? What do you think we are doing wrong here?

Thanks & regards


Solution

  • After looking deep, it is seen that when the request comes, its response is created and filled at this point. It has already HTML content inside. When trying to redirect new jsp file, it appends new HTML elements to the that response. Thus HTML elements inside response become obscure to Gate-in. In order to avoid this problem, resetting response is enough. It can be done resetting the response buffer, can be seen on the code;

         viewToRender = viewhandler.createView(context, errorView);
         context.setViewRoot(viewToRender);
         **((javax.portlet.RenderResponse) context.getExternalContext().getResponse()).resetBuffer();**
         viewhandler.renderView(context, viewToRender);