Adding <h: form> raises java.lang.IllegalStateException: cannot create a session after the response has been committed
I encounter the following exception on a very simple JSF 2 page after adding <h:form> :
java.lang.IllegalStateException: Cannot create a session after the response has been committed at org.apache.catalina.connector.Request.doGetSession(Request.java:2758) at org.apache.catalina.connector.Request.getSession(Request.java:2268) I am using Mojarra 2.1.3 and PrimeFaces3.0M4, on Tomcat 7.0.22 and JDK 7.
Page is a very simple data table:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui"> <h:head> </h:head> <h:body> <h:form> <p:dataTable var="car" value="#{tableBean.cars}"> ...... </p:dataTable> </h:form> </h:body> </html> The page displays correctly in the browser, but on the console I see an exception. The exception disappears if I delete <h:form> .
How is this caused and how can I solve it?
This is a known issue that you actually reported in issue 2215 . This will happen when the response buffer overflows (due to the large content) and the response is completed before the session is created. This is the result of Moharra’s overdoing efforts to postpone the “unnecessary” session creation as much as possible (which in itself is a good thing).
Until they are fixed, there are several ways:
Create a
FilterthatHttpServletRequest#getSession()beforeFilterChain#doFilter(). Benefit: No need to change JSF configuration / code. Disadvantage: when you also want to avoid unnecessary session creation.Call
ExternalContext#getSession()withtruein the bean (post)preRenderVieworpreRenderView. Advantage: in fact, nothing. Disadvantage: too hacks.Add a context parameter named
com.sun.faces.writeStateAtFormEndandfalseinweb.xml. Advantage: unnecessary session creation will be really eliminated, unlike # 1 and # 2. Disadvantage: now the reaction will be fully buffered in memory until</h:form>reached. If your forms are not very large, the impact should be minimal. However, it will still fail if your<h:form>starts relatively late in the view. It can be combined with C # 4.Add a context parameter named
javax.faces.FACELETS_BUFFER_SIZEand the Facelets response buffer size in bytes (for example,65535for 64 KB) so that all HTML output or at least<h:form>(see # 3) fits into response buffer. Advantage / disadvantage, see No. 3.Add a context parameter named
javax.faces.STATE_SAVING_METHODand valueclientinweb.xml. Advantage: A session is not created at all if you do not have a beans session. It also immediately resolves potential cases ofViewExpiredException. Disadvantage: increased use of network bandwidth. If you use partial state preservation, then the impact should be minimal.
Due to the fact that the problem disappears when you delete <h:form> , this is because the session does not need to be created in order to preserve the state of the view.
Update : this corresponds to duplicate issue 2277 , which has been fixed since Mojarra 2.1.8. That way you can just upgrade at least this version.
In the new version 2.1.21 released yesterday from javax.faces, this problem seems to have disappeared. Announce the new version:
<dependency> <groupId>org.glassfish</groupId> <artifactId>javax.faces</artifactId> <version>2.1.21</version> </dependency> and replace javax.faces.jar in the Glassfish modules folder, replacing javax.faces.jar for the new version 2.1.21.
In my case (myfaces-2.2.8 and Tomcat 8.0.23) the problem was a typo in the welcome welcome-file of web.xml . During debugging, I saw that Tomcat created, as expected, 404, but somehow myfaces tried to access the session, which then caused java.lang.IllegalStateException: Cannot create a session after the response has been committed . Using a valid page in the welcome-file of web.xml fixed the problem for me.
You may need to add the <f:view> and </f:view> elements before and after h:form , as well as add a link to the html tag for jsf tags
<html xmlns:f="http://java.sun.com/jsf/core"> for this.
If you use Spring MVC, and the call is made using Spring Forms, then we should use the GET method instead of POST (to receive data), and there should not be an input field that we can use.