Uploaded image for project: 'MyFaces Tomahawk'
  1. MyFaces Tomahawk
  2. TOMAHAWK-1442

ExtensionsResponseWrapper isCommitted breaks Liskov substitution principle

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 1.1.9
    • None
    • ExtensionsFilter
    • None

    Description

      I've been working on a project which mixes JSF and Servlets. And in a particulair Servlet I'm writing to the response (in some cases). Later on I check if the response has been committed, but this doesn't work with the ExtensionsResponseWrapper.

      The problem is this:
      --------------------------------------------------------
      HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getNativeResponse();

      //Write the response:
      response.getWriter().append(responseText.toString());

      //Make sure its flushed (and thus closed/committed)
      response.getWriter().flush();
      response.flushBuffer();

      log.debug(response.isCommitted);
      --------------------------------------------------------

      Results in: "false"

      But it should be 'true' since we've written to the response and flushed the writer and the buffer.
      From the HttpServletResponse JavaDoc:
      "Forces any content in the buffer to be written to the client. A call to this method automatically commits the response, meaning the status code and headers will be written."

      So the ExtensionsResponseWrapper is breaking the original contract, breaking the Liskov substitution principle.

      The reason is the internal delegate of the ExtensionsResponseWrapper. A new PrintWriter is used to write and read against, but the method isCommitted() is coupled to the state of the internal delegate (in the ServletResponseWrapper).

      My current work-around is:

      /** For Tomahawk's ExtensionsFilter we need this: */
      if(response instanceof ExtensionsResponseWrapper) {
      ((ExtensionsResponseWrapper)response).getDelegate().getWriter().append(responseText.toString());
      ((ExtensionsResponseWrapper)response).getDelegate().getWriter().flush();
      ((ExtensionsResponseWrapper)response).finishResponse();
      } else {
      response.getWriter().append(responseText.toString());
      response.getWriter().flush();
      response.flushBuffer();
      }

      This adds a new dependency to my framework which wasn't coupled to Tomahawk.. which I really don't want. But I can't seem to get it working otherwise.

      Attachments

        1. iscommitted_patch.txt
          12 kB
          Roy van Rijn

        Activity

          People

            Unassigned Unassigned
            yor Roy van Rijn
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated: