Keep the buffered response writer usable across responseReset() (#1033)

ServletExternalContextImpl.getResponseOutputWriter() caches a BufferedWriter. responseReset() and responseSendError() dropped that field, but a ResponseWriter created earlier in the render phase keeps writing into the instance it obtained back then, so everything rendered after the reset — typically an error page — landed in a buffer nobody drains and the client got HTTP 200 with an empty body. AjaxExceptionHandlerImpl and ErrorPageWriter follow the same reset-then-reuse pattern and were affected as well.

release() additionally flushed the BufferedWriter, which flushed the container writer and thereby committed the response, so a render exception on a non-ajax request could no longer be reset and forwarded to the error page.

Buffer through a ResettableBufferedWriter instead: it keeps its identity across a reset, discards the buffered chars there, resolves the container writer per drain, and drains without flushing the container writer.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2 files changed
tree: 1f9416e61b36bd717ba9ecdefce550473a62c616
  1. .github/
  2. api/
  3. assembly/
  4. benchmark/
  5. bundle/
  6. extensions/
  7. impl/
  8. integration-tests/
  9. parent/
  10. test/
  11. .asf.yaml
  12. .gitattributes
  13. .gitignore
  14. checkstyle.xml
  15. CI.md
  16. doap_MyFaces.rdf
  17. Jenkinsfile
  18. pom.xml
  19. README.md
README.md

Maven Central Build Status License Build Status ASF

Apache's implementation of the JavaServer Faces (JSF) and Jakarta Faces specification

Branches

main

Jakarta Faces 5.0 implementation

4.1.x

4.1.x Jakarta Faces 4.1 implementation

4.0.x

4.0.x Jakarta Faces 4.0 implementation
Based on the refactored 2.3-next codebase

2.3-next

2.3-next (Almost) JavaServer Faces 2.3 implementation
Completely refactored codebase compared to 2.3, also providing a Quarkus extension
2.3-next equals the JSF 2.3 API but delegates @ManagedBeans to CDI; ManagedBeans configured via XML are completely ignored. The implementation of the old FacesEL (javax.faces.el.*) also has been completely removed.

2.3.x

2.3 JavaServer Faces 2.3 implementation

Minimum Requirements (main)

  • Java 17+
  • Servlet 5.0+
  • EL 5.0+
  • CDI 4.0+
  • JSTL 3.0+ (optional)
  • BV 3.0+ (optional)

Installation

mvn clean install

Usage

Dependency

<dependency>
    <groupId>org.apache.myfaces.core</groupId>
    <artifactId>myfaces-api</artifactId>
    <version>5.0.0-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>org.apache.myfaces.core</groupId>
    <artifactId>myfaces-impl</artifactId>
    <version>5.0.0-SNAPSHOT</version>
</dependency>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

</web-app>

index.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:f="jakarta.faces.core"
  xmlns:h="jakarta.faces.html">

  <h:head>

  </h:head>

  <h:body>

    Hello World!

  </h:body>
</html>

Quarkus extension

Since 2.3-next a Quarkus extension is available. A sample project can be found here: https://github.com/apache/myfaces/blob/main/extensions/quarkus/showcase/

Not supported features:

  • Quarkus does not support session replication / passivation / clustering
  • Quarkus beans are not serializable and therefore session passivation would never work anyway
  • Quarkus does not implement @ConversationScoped
  • Quarkus does not support injection in normal objects, therefore injection in JSF artifacts like NavigationHandler etc. is not supported

Differences to a normal servlet container while developing

  • You need to put your views under src/main/resources/META-INF/resources as Quarkus doesn't create a WAR and src/main/webapp is ignored!