3

I am using Tomcat 6.0.32 with the Http11NioProtocol connector to implement long polling.

My comet processor is holding the HttpSevletResponse on a queue until an event is ready to send back. When it sends back the event it is writing a binary stream to an applet, so I use response.getOutputStream().write() to send data back. When writing to the stream it is synchronized.

When another web page in a second frame reloads (Independent JSP generated from SpringController in same container) occasionally I see this in the logs and the page fails to load.

Is it possible there is a concurrency error between a response generated from a comet processor and a regular servlet when both are requested at the same time?

The stack trace:

java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:611)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:180)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:118)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:77)
at org.apache.jsp.WEB_002dINF.jsp.sale_jsp._jspService(sale_jsp.java:96)
bluish
  • 26,356
  • 27
  • 122
  • 180
Adam
  • 85
  • 1
  • 2
  • 4
  • Have you tried using response.getWriter() instead? a la [This answer](http://stackoverflow.com/questions/1776142/getoutputstream-has-already-been-called-for-this-response/1776161#1776161) – Andrew Mar 18 '11 at 15:41
  • I need to use getOutputStream as I am sending bytes to the applet, not text – Adam Mar 18 '11 at 15:58
  • 1
    Could you maybe post some of your servlet's code? – brent777 Mar 18 '11 at 20:59

2 Answers2

2

As you can see in the stack trace, the JSP calls response.getWriter(), but the exception message says there was a call to response.getOutputStream() before. You cannot call both methods on the same response object.

This is the problem, I don't know how to solve it in your specific context..

bluish
  • 26,356
  • 27
  • 122
  • 180
0

About the possible concurrency: I don'y think so. Your long pooling Servlet is executed in another Thread, with its own HttpRequest and its own HttpResponse.

Your problem is located in your JSP as indicated: sale_jsp.java:96
Something is already commited in the response, so you're not allowed to use getOutputStream().

And it's very very easy in a JSP, this is a simple example:

<%@ page language="java" contentType="text/html;" %>
<%@ page import="java.io.*" %>

<% OutputStream os = response.getOutputStream(); 
   os.write(......);
%>

The generated Servlet will, at least, print 3 '\n' in the output before OutputStream os = response.getOutputStream(), so you're done..
To avoid this, remove every white spaces between %> and <%, like this:

<%@ page language="java" contentType="text/html;"
    import="java.io.*"   %><%

    OutputStream os = response.getOutputStream(); 
   os.write(......);
%>

Configure your Tomcat to keep the code generated.
Have a look to the generated code for your sale.jsp , I'm sure you'll find out what's wrong.

Also, be careful with <%! you should declare some variables and share them unintentionally over ALL requests on this JSP this could lead to that kind of concurrency...

Destroyica
  • 4,147
  • 3
  • 33
  • 50