Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cannot create session after response has been committed

i am getting the following error on my application startup page load :

 SEVERE: Error Rendering View[/HomeTemplate/equityVolume.xhtml]
javax.el.ELException: /HomeTemplate/equityVolume.xhtml @70,78 value="#{equityBean.scripList}": java.lang.IllegalStateException: PWC3999: Cannot create a session after the response has been committed...

    Caused by: java.lang.IllegalStateException: PWC3999: Cannot create a session after the response has been committed...

i get this error when i apply the css to my homepage, the error disappears when i remove the css template(but i want to aplly the css template) following is the bean code snippet that causes the error(found by debugging)

public List<MasterScrip> getScripList() {
   HttpServletRequest req=(HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest(); //error line
   HttpSession session=req.getSession();
   type=(String)session.getAttribute("type");...

xhtml code:

<h:body>
    <ui:composition template="commonClientLayout.xhtml">

    <ui:define name="contentFile">
            <div id="content">
    <h:form id="frm">...

when i remove the ui:composition and define tags(i.e. if i dont apply the css), then i dont get this error. what could be causing this error and how do i solve it?

edited:

    @PostConstruct
void initialiseSession() {
    if(type!=null)
      {
       if(type.equalsIgnoreCase("losers"))
       {
        scripList=new ArrayList<MasterScrip> ();
        scripList=getScripByPriceLosers(exchange);
       // return scripList;
       }
       else if(type.equalsIgnoreCase("gainers"))
       {
        scripList=new ArrayList<MasterScrip> ();
     scripList=getScripByPriceGainers(exchange);
       // return scripList;
       }
       else
       {
           scripList=new ArrayList<MasterScrip> ();
     scripList=getScripByVolumeType(exchange);
     //  return scripList;
       }
      }
      else
      {
          scripList=new ArrayList<MasterScrip> ();
     scripList=getScripByVolumeType(exchange);
      }

}

    public List<MasterScrip> getScripList() {
       return scripList;

    }

edited again:

 SEVERE: Error Rendering View[/equityVolume.xhtml]
java.lang.IllegalStateException
    at org.apache.catalina.connector.ResponseFacade.setBufferSize(ResponseFacade.java:275)...

edit: web.xml

    <?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Production</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
        <param-value>65535</param-value>
    </context-param>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>

    </session-config>
    <welcome-file-list>
        <welcome-file>equityVolume.xhtml</welcome-file>
    </welcome-file-list>
    <security-constraint>
        <display-name>Constraint1</display-name>
        <web-resource-collection>
            <web-resource-name>AdminTemplate</web-resource-name>
            <description/>
            <url-pattern>/AdminTemplate/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <description/>
            <role-name>admin</role-name>
        </auth-constraint>
    </security-constraint>
    <security-constraint>
        <display-name>Constraint2</display-name>
        <web-resource-collection>
            <web-resource-name>ClientTemplate</web-resource-name>
            <description/>
            <url-pattern>/ClientTemplate/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <description/>
            <role-name>client</role-name>
        </auth-constraint>
    </security-constraint>
    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>DataRealm</realm-name>
        <form-login-config>
            <form-login-page>/equityVolume.xhtml</form-login-page>
            <form-error-page>/errorpage.xhtml</form-error-page>
        </form-login-config>
    </login-config>
    <security-role>
        <description/>
        <role-name>admin</role-name>
    </security-role>
    <security-role>
        <description/>
        <role-name>client</role-name>
    </security-role>
</web-app>
like image 799
z22 Avatar asked Jun 08 '12 13:06

z22


1 Answers

You shouldn't be doing business job in getters. Do it in the bean (post)constructor instead.

Your concrete problem is caused because you're requesting a relatively large page on a fresh new browser session for which the server HttpSession hasn't been created yet and the EL expression #{equityBean.scripList} is referenced relatively late in the page.

The response buffer is by default 2KB and when it overflows due to a large response, then it will be committed. This means that all response headers will be sent and that first ~2KB of the HTML output will be sent. Then, after that point, the EL expression #{equityBean.scripList} will be resolved wherein you're trying to get the session. If the server HttpSession hasn't been created yet at that moment, then the server needs to set a cookie in the response header in order to maintain it for subsequent requests. But that's of course not possible if the response has already been committed. Hence this exception.

As said, just do the job in bean's (post)constructor instead. Or just inject it as managed property.

@ManagedProperty("#{type}")
private String type;

If the exception still occurs, you're probably using an older version of Mojarra which suffers from the bug as described in issues 2215 and 2277 which is caused by too extreme postponing of the "unnecessary" session creation. This has been fixed since Mojarra 2.1.8. So, upgrading to it or newer (it's currently 2.1.9) should do it.


Unrelated to the concrete problem, the getScripList() logic is by the way smelly. But that's subject for a different problem/question. Are you aware that you can just access the session attribute with name "type" in EL as #{type}? Are you aware that having raw javax.servlet.* imports in a JSF backing bean class more than often indicate that you're possibly doing things the wrong way and that there may be more "JSF-ish" ways to achieve the concrete functional requirement?

like image 197
BalusC Avatar answered Oct 02 '22 21:10

BalusC