Bug 37516 - A committed HttpServletResponse is passed to the doGet() method
A committed HttpServletResponse is passed to the doGet() method
Status: RESOLVED INVALID
Product: Tomcat 5
Classification: Unclassified
Component: Servlet & JSP API
5.5.9
All All
: P2 critical with 1 vote (vote)
: ---
Assigned To: Tomcat Developers Mailing List
:
Depends on:
Blocks:
  Show dependency tree
 
Reported: 2005-11-16 00:07 UTC by Adriano Oliveira
Modified: 2005-11-16 12:59 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Adriano Oliveira 2005-11-16 00:07:24 UTC
I'm getting a committed HttpServletResponse object in my doGet() without 
executing any command that could change its state to committed. Some of the 
times this error has occurred I noticed that the response was committed even 
before the first command in the doGet method. I don't get this behavior on Sun 
Java System Application Server 8.1. I got this behavior on Tomcat 5.5.7, 
5.5.9, 5.5.12 both on Windows XP and Linux (Fedora 2).

I'm sending a brief code to simulate this error (two servlets and the 
descriptor. Please note that in order to test this code you may have to change 
the port number in the HTML generated in Test.java. Also, the generated page 
uses a HTML Header to automatically refreshs the page every second to spare 
the person who's testing to press F5. But one can erase this Refresh-Header 
and do the refreshs by pressing F5 and after some refreshs the error will 
occur).

//*********** web.xml ***************
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <servlet>
    <servlet-name>Test</servlet-name>
    <servlet-class>Test</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>Image</servlet-name>
    <servlet-class>Image</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Test</servlet-name>
    <url-pattern>/test</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Image</servlet-name>
    <url-pattern>*.jpg</url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>
            30
        </session-timeout>
  </session-config>
</web-app>



// ******************* Test.java ***********************************
// Note: if you use a port number other than 8080 please change the line 
out.println("<img alt=\"image\" src=\"http://localhost:8080/... in Test.java

import java.io.*;
import java.net.*;
 
import javax.servlet.*;
import javax.servlet.http.*;
 
/**
 *
 * @author Adriano
 * @version
 */
public class Test extends HttpServlet {
    
    protected void processRequest(HttpServletRequest request, 
HttpServletResponse response)
    throws ServletException, IOException {
        if (response.isCommitted()) {
            System.out.println("Response is committed in Test.processRequest");
        }
        
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head>");
        out.println("<meta http-equiv=\"Refresh\" content=\"1\">");
        out.println("<title>Servlet Test</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<img alt=\"image\" 
src=\"http://localhost:8080/BugTest/image.jpg\"");
        out.println("</body>");
        out.println("</html>");
        out.close();
    }
    
    protected void doGet(HttpServletRequest request, HttpServletResponse 
response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
    
    protected void doPost(HttpServletRequest request, HttpServletResponse 
response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
}


//******************************* Image.java *************************
 
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
 
import javax.servlet.*;
import javax.servlet.http.*;
 
/**
 *
 * @author Adriano
 * @version
 */
public class Image extends HttpServlet {
    
    protected void processRequest(HttpServletRequest request, 
HttpServletResponse response)
    throws ServletException, IOException {
        
        if (response.isCommitted()) {
            System.out.println("Response is committed in 
Image.processRequest");
        }
        
        response.setContentType("image/jpg");
        response.setBufferSize(8192);
        
        OutputStream out = response.getOutputStream();
        
        //Generates an image
        BufferedImage image = new BufferedImage(100, 100, 
BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = image.createGraphics();
        Font font = new Font("Arial", Font.BOLD, 20);
        graphics.setFont(font);
        graphics.drawString("Test", 20, 20);
        Iterator writers = ImageIO.getImageWritersByFormatName("jpg");
        ImageWriter writer = (ImageWriter)writers.next();
        ImageOutputStream imageOutput = ImageIO.createImageOutputStream(out);
        writer.setOutput(imageOutput);
        writer.write(image);
        writer.dispose();
        
        out.close();
        
        response.flushBuffer();
    }
    
    protected void doGet(HttpServletRequest request, HttpServletResponse 
response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
    
    protected void doPost(HttpServletRequest request, HttpServletResponse 
response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
    
}
Comment 1 Remy Maucherat 2005-11-16 21:59:13 UTC
I looked at that issue in the past, and Java2D accesses the streams outside of
the service methods.