ICEpush
  1. ICEpush
  2. PUSH-116

Verify Servlet 3.0 support on Tomcat 7

    Details

    • Type: Task Task
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0-Beta
    • Fix Version/s: 2.0.1
    • Component/s: Push Library
    • Labels:
      None
    • Environment:
      ICEfaces, Tomcat 7

      Description


      When ICEfaces is configured to use Servlet 3.0, the following Exception occurs with ICEpush:


      Caused by: java.lang.IllegalStateException: Calling [asyncComplete()] is not valid for a request with Async state [DISPATCHED]
      at org.apache.coyote.AsyncStateMachine.asyncComplete(AsyncStateMachine.java:186)
      at org.apache.coyote.http11.Http11Processor.actionInternal(Http11Processor.java:506)
      at org.apache.coyote.http11.AbstractHttp11Processor.action(AbstractHttp11Processor.java:809)
      at org.apache.coyote.Request.action(Request.java:344)
      at org.apache.catalina.core.AsyncContextImpl.complete(AsyncContextImpl.java:83)
      at org.icepush.servlet.AsyncAdaptingServlet$AsyncRequestResponse.respondWith(AsyncAdaptingServlet.java:66)
      at org.icepush.BlockingConnectionServer.respondIfPendingRequest(BlockingConnectionServer.java:196)

        Activity

        Hide
        Ted Goddard added a comment -

        Looks like Tomcat 7 fails in the same way as GlassFish 3.0.1.

        Show
        Ted Goddard added a comment - Looks like Tomcat 7 fails in the same way as GlassFish 3.0.1.
        Hide
        Mircea Toma added a comment -

        Indeed ICEpush with Tomcat 7.0 and async. support enabled does not work. The responses on the blocking connection seem to have the correct content (fixed sized), but the content is marked as 'chunked' which confuses the browser.

        Show
        Mircea Toma added a comment - Indeed ICEpush with Tomcat 7.0 and async. support enabled does not work. The responses on the blocking connection seem to have the correct content (fixed sized), but the content is marked as 'chunked' which confuses the browser.
        Hide
        Mircea Toma added a comment - - edited

        The reason why ICEpush fails in Tomcat 7.06 is due to the HTTP headers missing in the blocking connection response.

        To find out more about how Tomcat 7 works I devised a simple test, a servlet that parks the request and then after 5 seconds responds.
        Setting the headers just before the response is sent does not succeed in actually sending the headers over the wire:

        protected void doGet(HttpServletRequest request, final HttpServletResponse r) throws ServletException, IOException {
        final AsyncContext ctx = request.startAsync();
        ctx.start(new Runnable() {
        public void run() {
        try

        { Thread.sleep(5000); r.setHeader("bla", "fffff"); r.setContentType("text/plain"); r.setContentLength("------".getBytes().length); r.getWriter().print("------"); ctx.complete(); }

        catch (Exception e)

        { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. }
        }
        });
        }

        Setting the headers on the request thread before or after the AsyncContext is acquired succeeds in sending the headers over the wire:

        protected void doGet(HttpServletRequest request, final HttpServletResponse r) throws ServletException, IOException {
        final AsyncContext ctx = request.startAsync();
        r.setHeader("bla", "fffff");
        r.setContentType("text/plain");
        r.setContentLength("------".getBytes().length);
        r.getWriter().print("------");
        ctx.start(new Runnable() {
        public void run() {
        try { Thread.sleep(5000); ctx.complete(); } catch (Exception e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. }

        }
        });
        }

        Show
        Mircea Toma added a comment - - edited The reason why ICEpush fails in Tomcat 7.06 is due to the HTTP headers missing in the blocking connection response. To find out more about how Tomcat 7 works I devised a simple test, a servlet that parks the request and then after 5 seconds responds. Setting the headers just before the response is sent does not succeed in actually sending the headers over the wire: protected void doGet(HttpServletRequest request, final HttpServletResponse r) throws ServletException, IOException { final AsyncContext ctx = request.startAsync(); ctx.start(new Runnable() { public void run() { try { Thread.sleep(5000); r.setHeader("bla", "fffff"); r.setContentType("text/plain"); r.setContentLength("------".getBytes().length); r.getWriter().print("------"); ctx.complete(); } catch (Exception e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } }); } Setting the headers on the request thread before or after the AsyncContext is acquired succeeds in sending the headers over the wire: protected void doGet(HttpServletRequest request, final HttpServletResponse r) throws ServletException, IOException { final AsyncContext ctx = request.startAsync(); r.setHeader("bla", "fffff"); r.setContentType("text/plain"); r.setContentLength("------".getBytes().length); r.getWriter().print("------"); ctx.start(new Runnable() { public void run() { try { Thread.sleep(5000); ctx.complete(); } catch (Exception e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } }); }
        Hide
        Ken Fyten added a comment -

        Need to see if there's a Tomcat bug issue reported for this, and if not, report it.

        Show
        Ken Fyten added a comment - Need to see if there's a Tomcat bug issue reported for this, and if not, report it.
        Hide
        Ted Goddard added a comment -

        Setting the contentType prior to async operations seems to fix the problem:

        response.setContentType("text/xml");
        asyncContext = request.isAsyncStarted() ? request.getAsyncContext() : request.startAsync();

        Show
        Ted Goddard added a comment - Setting the contentType prior to async operations seems to fix the problem: response.setContentType("text/xml"); asyncContext = request.isAsyncStarted() ? request.getAsyncContext() : request.startAsync();
        Hide
        Ted Goddard added a comment -

        Since the contentType can likely be set twice, the recommended fix is to call setContentType as above, then rely on re-setting it in other cases. This will at least have the effect of supporting Servlet 3.0 except under error conditions.

        Show
        Ted Goddard added a comment - Since the contentType can likely be set twice, the recommended fix is to call setContentType as above, then rely on re-setting it in other cases. This will at least have the effect of supporting Servlet 3.0 except under error conditions.
        Hide
        Ted Goddard added a comment -

        The current Tomcat implementation may be expecting that the headers are set prior to the return of the original service() method.

        Show
        Ted Goddard added a comment - The current Tomcat implementation may be expecting that the headers are set prior to the return of the original service() method.
        Hide
        Mircea Toma added a comment -

        Set default text/xml content type to workaround Tomcat's limitation (headers are sent only when added on the request thread).

        Show
        Mircea Toma added a comment - Set default text/xml content type to workaround Tomcat's limitation (headers are sent only when added on the request thread).
        Hide
        Mircea Toma added a comment -

        Issue recorded in Tomcat's bug tracking system: https://issues.apache.org/bugzilla/show_bug.cgi?id=50753

        Show
        Mircea Toma added a comment - Issue recorded in Tomcat's bug tracking system: https://issues.apache.org/bugzilla/show_bug.cgi?id=50753
        Hide
        Mircea Toma added a comment -

        Looks like the issue was already fix in Tomcat 7.0.8 version.

        Show
        Mircea Toma added a comment - Looks like the issue was already fix in Tomcat 7.0.8 version.

          People

          • Assignee:
            Mircea Toma
            Reporter:
            Ted Goddard
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: