title: JSF 2 + PrettyFaces -> IllegalStateException: PWC3990: getWriter() has already been called for this response
body: <p>I have a Java EE App that has JSF2 + PrettyFaces + Facelets + EJB3 + EclipseLink.</p>
  
  <p>I'm continually running into an IllegalStateException as stated above, due to some inconsistencies in the JSF2 + Faceletes rendering model to work along with PrettyFaces and h:link tag.</p>
  
  <p>I removed all my old JSTL tags and also all the commandLink tags, according to good practices when using JSF2 + Faceletes. </p>
  
  <p>In web.xml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;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"&gt;
    &lt;display-name&gt;atlPortal&lt;/display-name&gt;
  
      &lt;context-param&gt;
          &lt;param-name&gt;com.sun.faces.prefer.XHTML&lt;/param-name&gt;
          &lt;param-value&gt;true&lt;/param-value&gt;
      &lt;/context-param&gt;
  
    &lt;context-param&gt;
      &lt;param-name&gt;javax.faces.PROJECT_STAGE&lt;/param-name&gt;
      &lt;param-value&gt;Development&lt;/param-value&gt;
    &lt;/context-param&gt;
  
      &lt;context-param&gt;
          &lt;param-name&gt;javax.faces.FACELETS_LIBRARIES&lt;/param-name&gt;
          &lt;param-value&gt;/WEB-INF/facelets/customTags.taglib.xml&lt;/param-value&gt;
      &lt;/context-param&gt;
  
    &lt;servlet&gt;
          &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
          &lt;servlet-class&gt;javax.faces.webapp.FacesServlet&lt;/servlet-class&gt;
          &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
    &lt;/servlet&gt;
  
    &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
      &lt;url-pattern&gt;*.faces&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;
  
      &lt;servlet&gt;
          &lt;servlet-name&gt;imageServlet&lt;/servlet-name&gt;
          &lt;servlet-class&gt;com.mindvortex.atl.web.common.servlet.ImageServlet&lt;/servlet-class&gt;
          &lt;load-on-startup&gt;2&lt;/load-on-startup&gt;
      &lt;/servlet&gt;
  
      &lt;servlet-mapping&gt;
          &lt;servlet-name&gt;imageServlet&lt;/servlet-name&gt;
          &lt;url-pattern&gt;/image/*&lt;/url-pattern&gt;
          &lt;url-pattern&gt;/pages/image/*&lt;/url-pattern&gt;
          &lt;url-pattern&gt;/pages/protected/image/*&lt;/url-pattern&gt;
      &lt;/servlet-mapping&gt;
  
      &lt;filter&gt;
         &lt;filter-name&gt;Pretty Filter&lt;/filter-name&gt;
         &lt;filter-class&gt;com.ocpsoft.pretty.PrettyFilter&lt;/filter-class&gt;    
         &lt;async-supported&gt;false&lt;/async-supported&gt;    
      &lt;/filter&gt;
  
      &lt;filter-mapping&gt; 
         &lt;filter-name&gt;Pretty Filter&lt;/filter-name&gt;    
         &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
         &lt;dispatcher&gt;FORWARD&lt;/dispatcher&gt; 
         &lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt;
         &lt;dispatcher&gt;ERROR&lt;/dispatcher&gt;
      &lt;/filter-mapping&gt;
  
    &lt;listener&gt;
      &lt;listener-class&gt;com.sun.faces.config.ConfigureListener&lt;/listener-class&gt;
    &lt;/listener&gt;
  
    &lt;!-- servlets and such would be above --&gt;
  
      &lt;login-config&gt;
          &lt;auth-method&gt;FORM&lt;/auth-method&gt;
          &lt;realm-name&gt;userauth&lt;/realm-name&gt;
          &lt;form-login-config&gt;
              &lt;form-login-page&gt;/login.faces&lt;/form-login-page&gt;
              &lt;form-error-page&gt;/loginError.xhtml&lt;/form-error-page&gt;
          &lt;/form-login-config&gt;                
      &lt;/login-config&gt;
  
      &lt;security-constraint&gt;
          &lt;display-name&gt;Block All XHTML&lt;/display-name&gt;
          &lt;web-resource-collection&gt;
              &lt;web-resource-name&gt;blockXHTML&lt;/web-resource-name&gt;
              &lt;description&gt;&lt;/description&gt;
              &lt;url-pattern&gt;*.xhtml&lt;/url-pattern&gt;
              &lt;http-method&gt;GET&lt;/http-method&gt;
              &lt;http-method&gt;POST&lt;/http-method&gt;
              &lt;http-method&gt;HEAD&lt;/http-method&gt;
              &lt;http-method&gt;PUT&lt;/http-method&gt;
              &lt;http-method&gt;OPTIONS&lt;/http-method&gt;
              &lt;http-method&gt;TRACE&lt;/http-method&gt;
              &lt;http-method&gt;DELETE&lt;/http-method&gt;
          &lt;/web-resource-collection&gt;
          &lt;auth-constraint /&gt;             
      &lt;/security-constraint&gt;
  
  
      &lt;security-constraint&gt;   
          &lt;display-name&gt;ConstraintSSL&lt;/display-name&gt;
          &lt;web-resource-collection&gt;
              &lt;web-resource-name&gt;protected&lt;/web-resource-name&gt;
              &lt;description/&gt;
              &lt;url-pattern&gt;/pages/protected/*&lt;/url-pattern&gt;
              &lt;url-pattern&gt;/login/*&lt;/url-pattern&gt;
              &lt;url-pattern&gt;/login.*&lt;/url-pattern&gt;
              &lt;url-pattern&gt;/account/*&lt;/url-pattern&gt;
              &lt;http-method&gt;GET&lt;/http-method&gt;
              &lt;http-method&gt;POST&lt;/http-method&gt;
              &lt;http-method&gt;HEAD&lt;/http-method&gt;
              &lt;http-method&gt;PUT&lt;/http-method&gt;
              &lt;http-method&gt;OPTIONS&lt;/http-method&gt;
              &lt;http-method&gt;TRACE&lt;/http-method&gt;
              &lt;http-method&gt;DELETE&lt;/http-method&gt;
          &lt;/web-resource-collection&gt;
  
          &lt;user-data-constraint&gt;
            &lt;description&gt;SSL not required for Development&lt;/description&gt;
            &lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;
          &lt;/user-data-constraint&gt;        
      &lt;/security-constraint&gt;
  
      &lt;security-constraint&gt;   
          &lt;display-name&gt;ConstraintUser&lt;/display-name&gt;
          &lt;web-resource-collection&gt;
              &lt;web-resource-name&gt;user&lt;/web-resource-name&gt;
              &lt;description/&gt;
              &lt;url-pattern&gt;/account/*&lt;/url-pattern&gt;
              &lt;http-method&gt;GET&lt;/http-method&gt;
              &lt;http-method&gt;POST&lt;/http-method&gt;
              &lt;http-method&gt;HEAD&lt;/http-method&gt;
              &lt;http-method&gt;PUT&lt;/http-method&gt;
              &lt;http-method&gt;OPTIONS&lt;/http-method&gt;
              &lt;http-method&gt;TRACE&lt;/http-method&gt;
              &lt;http-method&gt;DELETE&lt;/http-method&gt;
          &lt;/web-resource-collection&gt;
          &lt;auth-constraint&gt;       
              &lt;description/&gt;
              &lt;role-name&gt;ADMINISTRATORS&lt;/role-name&gt;
              &lt;role-name&gt;USERS&lt;/role-name&gt;
          &lt;/auth-constraint&gt;
  
          &lt;user-data-constraint&gt;
            &lt;description&gt;SSL not required for Development&lt;/description&gt;
            &lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;
          &lt;/user-data-constraint&gt;        
      &lt;/security-constraint&gt;
  
      &lt;security-role&gt;
          &lt;description/&gt;
          &lt;role-name&gt;USERS&lt;/role-name&gt;
      &lt;/security-role&gt;
      &lt;security-role&gt;
          &lt;description/&gt;
          &lt;role-name&gt;ADMINISTRATORS&lt;/role-name&gt;
      &lt;/security-role&gt;
  
    &lt;session-config&gt;
      &lt;session-timeout&gt;30&lt;/session-timeout&gt;
      &lt;tracking-mode&gt;COOKIE&lt;/tracking-mode&gt;
    &lt;/session-config&gt;
  
     &lt;welcome-file-list&gt;
      &lt;welcome-file&gt;init.faces&lt;/welcome-file&gt;    
     &lt;/welcome-file-list&gt;
  
  &lt;/web-app&gt;
  </code></pre>
  
  <p>This happens whenever I navigate from one XHTML page to another via 
  
  <pre><code>                        &lt;h:link outcome="pretty:viewContactUs" styleClass="nav6"&gt;
                              #{msg['contactUs']}
                          &lt;/h:link&gt;                                                                                                                                      
  </code></pre>
  
  <p>in pretty-faces.xml</p>
  
  <pre><code>  &lt;url-mapping id="viewContactUs"&gt;
        &lt;pattern value="/contactUs/" /&gt;
        &lt;view-id value="contactUs.faces" /&gt;
        &lt;action&gt;#{commentsMB.openContactUs}&lt;/action&gt;
    &lt;/url-mapping&gt;            
  </code></pre>
  
  <p>in CommentsMB Managed Bean:</p>
  
  <pre><code>@ManagedBean
  @RequestScoped
  public class CommentsMB extends UserCrudMB&lt;Comments, Integer&gt; {
  
      private static final long serialVersionUID = 1L;
  
      @EJB(mappedName="ejb/CommentsService")
      private CommentsServiceBeanLocal commentsService;
  
  // ... Code
  
      public String openContactUs() {
          this.entity = new Comments();
          return NavigationViews.VIEW_CONTACT_US;
      }
  
  }
  </code></pre>
  
  <p>in faces-config.xml:</p>
  
  <pre><code>   &lt;navigation-rule&gt;
          &lt;from-view-id&gt;/*&lt;/from-view-id&gt;
          &lt;navigation-case&gt;
              &lt;from-outcome&gt;contactUs&lt;/from-outcome&gt;
              &lt;to-view-id&gt;/pages/contactUs.xhtml&lt;/to-view-id&gt;         
          &lt;redirect /&gt;&lt;/navigation-case&gt;
  </code></pre>
  
  <p>in contactUs.xhtml:</p>
  
  <pre><code>                    &lt;div class="form_row"&gt;
                          &lt;h:link id="commentsSave" outcome="pretty:commentsSave" styleClass="contact"&gt;
                              #{msg.send}
                          &lt;/h:link&gt;
                      &lt;/div&gt;
  </code></pre>
  
  <p>The error happens just when I click the commentsSave Button. It gives: IllegalStateException: PWC3990: getWriter() has already been called for this response.</p>
  
  <p>the pretty-config.xml for commentsSave URL mapping:</p>
  
  <pre><code>  &lt;url-mapping id="commentsSave"&gt;
        &lt;pattern value="/comments/save/" /&gt;
        &lt;view-id value="contactUs.faces" /&gt;
        &lt;action&gt;#{commentsMB.save}&lt;/action&gt;
    &lt;/url-mapping&gt;                       
  </code></pre>
  
  <p>CommentsMB save action signature:</p>
  
  <pre><code>public String save() {
      return save(this.getEntity());
  }
  </code></pre>
  
  <p>The commentsMB.save Bean action is not called and I get a page not found error with the exception thrown in the logs.</p>
  
  <p>StackTrace:</p>
  
  <pre><code>[#|2012-03-30T13:47:54.968-0300|SEVERE|glassfish3.1.1|org.apache.jasper.servlet.JspServlet|_ThreadID=25;_ThreadName=http-thread-pool-8084(4);|PWC6117:
   File "C%3A%5CGBL%5Cprop%5Cprogs%5Cglassfish-3.1.1%5Cglassfish3%5Cglassfish%5Cdomains%5Cdomain1%5Capplications%5CatlanteusEAR%5CatlanteusPortal-1.0.0_
  war%5Ccomments%5Csave%5CcontactUs.jsp" not found|#]
  
  [#|2012-03-30T13:47:54.976-0300|WARNING|glassfish3.1.1|org.apache.catalina.core.ApplicationDispatcherForward|_ThreadID=25;_ThreadName=http-thread-pool
  -8084(4);|Exception processing ErrorPage[errorCode=404, location=/pages/error/error404.xhtml]
  java.lang.IllegalStateException: PWC1227: Cannot forward after response has been committed
          at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:370)
          at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:350)
          at org.apache.catalina.core.ApplicationDispatcherForward.custom(ApplicationDispatcherForward.java:253)
          at org.apache.catalina.core.ApplicationDispatcherForward.status(ApplicationDispatcherForward.java:209)
          at org.apache.catalina.core.ApplicationDispatcherForward.commit(ApplicationDispatcherForward.java:131)
          at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:353)
          at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:300)
          at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:110)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
          at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
          at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
          at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
          at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
          at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
          at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
          at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
          at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
          at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
          at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
          at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
          at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
          at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
          at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
          at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
          at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
          at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
          at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
          at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
          at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
          at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
          at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
          at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
          at java.lang.Thread.run(Thread.java:619)
  |#]
  </code></pre>
  
  <p>Seems that JSF is interpreting the navigation as a .jsp altough I use XHTML only.</p>
  
  <p>Could someone help me figure out what am I doing wrong ? This is my major issue since I began using JSF2 + Facelets.</p>