See intermixed. On Thu, 9 May 2002, Steve McCarthy wrote:
> Date: Thu, 09 May 2002 15:44:30 -0700 > From: Steve McCarthy <[EMAIL PROTECTED]> > Reply-To: Tomcat Developers List <[EMAIL PROTECTED]> > To: Tomcat Developers List <[EMAIL PROTECTED]> > Subject: Re: Prove me wrong - take this quiz > > Remy Maucherat wrote: > > >>Question 1 > >> Does servlet specification require you to call flush() to ensure that > >> the client actually see the bytes? > >> A. No, spec does not mandate this behavior for webapps. > >> B. "you have to flush your writer. Otherwise, because of timing > >> problems, the bytes will not get written" (bug 8916) > >> > > > >If you instantiate a buffered writer yourself (instead of using > >resp.getWriter) > >to wrap around resp.getOutputStream, you have to flush it. > >So it's B. > > > Wrong again, Remy. And please stop introducing diversions like > "instantiating a buffered writer yourself." The bug exists with the > Writer returned from the container. > > Please go the the Java Servlet Specification, v2.2 Final Release. > Where does it put the burden of flushing buffer on the web application? > Please cite the chapter and section. Of course you can't because it is > not there. > > Why is Tomcat 4.0.x is the only servlet container that requires this > strange behavior? Old JServ didn't. WebLogic doesn't. > > I don't see how a reasonable developer can not answer "A". > > Also, what is this business you said about "because of timing problems, > the bytes will not get written?" Do other developers agree with this > statement? > Being somewhat familiar with the servlet specs (I've been on the expert groups for 2.2, 2.3, and 2.4 :-), the following two scenarios have the potential to behave differently, depending on implementation-specific decisions inside both the servlet container and the JDK: (a) Write directly to ServletOutputStream: public class MyServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { ServletOutputStream sos = response.getOutputStream(); sos.print("foo"); // No flush on sos } } (b) Write to a buffered wrapper around ServletOutputStream: public class MyServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { ServletOutputStream sos = response.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(sos); sos.print("foo"); // No flush on bos or sos } } In scenario (a), the three characters will be written to the response -- the container flushes the container-provided stream for you. In scenario (b), the three characters will *not* be written to the response -- they are sitting inside the buffer in the BufferedOutputStream, and are not accessible to the container -- it doesn't even know that the wrapping class is there. You have to call bos.flush() in order for them to be written. (Exactly the same issue is true with all of the standard Java output objects - this is not specific to servlet containers). Scenario (b) is also a very common problem in a servlet 2.3 environment, when you use a Filter to create a response wrapper (for instance, to do an XSLT transformation on the output generated by the servlet. It is the application's responsibility to ensure that the output stream or writer it creates in the wrapper is indeed flushed before the filter returns. Usually, that's just a matter of ensuring that you flush it after the chain.doFilter() method returns, and before you yourself return from the filter. Steve, your original example in bug report 8916 is exactly analogous to scenario (b), because you are creating a java.io.PrintWriter wrapper around the ServletOutputStream provided by the container. It is entirely legal for a java.io.PrintWriter implementation to buffer things up inside itself -- programs that rely on this *not* happening are incorrect, even if they happen to work in *some* environments. Note also that it's entirely irrelevant whether ErrorReportValve is involved or not -- user objects that wrap the container-provided stream or writer *must* be flushed in order to guarantee that the output actually gets written. Even if you had returned a status 200 (so that the error reporting mechanism wasn't involved), you would not have seen the actual character "written" by your test servlet. I haven't looked at bug report 8831 yet, but 8916 is definitely an application error. Craig -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>