views:

17

answers:

1

I use Orchestra and RichFaces in my application. When accessing a page in my application I get the following error many times and the page doesn't load:

WARN _ReentrantLock:103 - Waited for longer than 30000 milliseconds for access to lock org.apache.myfaces.orchestra.lib._ReentrantLock@78214f6b which is locked by thread http-8080-2

I believe at the heart the problem is a filter that I use for authentication. Here is its code (conversationController is a conversation scoped bean):

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,  FilterChain chain)
    throws IOException, ServletException
    {           
        FacesContextBuilder builder = new FacesContextBuilder();

        FacesContext facesContext = builder.getFacesContext(request, response);
        ServletContext servletContext = (ServletContext) facesContext.getExternalContext().getContext();
        Application application = facesContext.getApplication();
        ELContext elContext = facesContext.getELContext();
        ConversationController conversationController = (ConversationController) application.getELResolver().getValue(elContext, null, "conversationController");
        SessionController sessionController = (SessionController) application.getELResolver().getValue(elContext, null, "sessionController");
        ApplicationController applicationController = (ApplicationController) application.getELResolver().getValue(elContext, null, "applicationController");
        EntityRegistry entityRegistry = conversationController.getEntityRegistry();     

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse= (HttpServletResponse) response;

        User currentUser = sessionController.getCurrentUser();

        Boolean isTesting = (Boolean) servletContext.getAttribute("ginger.TESTING");
        if (isTesting == null) isTesting = false;

        if (currentUser == null)
        {
            if (httpRequest.isSecure() || isTesting)
            {               
                Cookie[] cookies = httpRequest.getCookies();
                Cookie cookie = null;

                if (cookies != null)
                {
                    for (int i=0; i<cookies.length; i++)
                    {
                        if (cookies[i].getName().equals("ginger.USERCOOKIE"))
                        {
                            cookie = cookies[i];
                            break;
                        }
                    }
                }

                if (cookie != null)
                {
                    currentUser = entityRegistry.getUserByCookie(cookie.getValue()); 
                }

                if (currentUser == null)
                {
                    currentUser = new UnregisteredUser();

                    String cookieValue = String.valueOf(applicationController.getRandom());

                    currentUser.setCookie(cookieValue);

                    entityRegistry.storeUser(currentUser);

                    cookie = new Cookie("ginger.USERCOOKIE", cookieValue);
                    cookie.setPath(applicationController.getPath());
                    cookie.setMaxAge(365*24*60*60);
                    if (!isTesting) cookie.setSecure(true);

                    httpResponse.addCookie(cookie);
                }

                sessionController.setCurrentUser(currentUser);

                @SuppressWarnings("unchecked")
                String url = URLConstructor.constructUrl(servletContext, httpRequest, httpResponse, false, httpRequest.getRequestURI(), httpRequest.getParameterMap());

                httpResponse.sendRedirect(url);
            }
            else
            {
                @SuppressWarnings("unchecked")
                String url = URLConstructor.constructUrl(servletContext, httpRequest, httpResponse, true, httpRequest.getRequestURI(), httpRequest.getParameterMap());

                httpResponse.sendRedirect(url);
            }
        }
        else
        {
            chain.doFilter(request, response);
        }

        builder.removeFacesContext();
    }
A: 

I solved this by releasing the FacesContext before the response is committed. Like this:

@SuppressWarnings("unchecked")
String url = URLConstructor.constructUrl(servletContext, httpRequest, httpResponse, true, httpRequest.getRequestURI(), httpRequest.getParameterMap());
builder.removeFacesContext();
httpResponse.sendRedirect(url);

I don't understand this completely but it seems that the new request was still using the old FacesContext and this interfered with the _ReentrantLock getting unlocked.

Panayiotis Karabassis