When an exception occurs in the execution of async dispatch(),
web container MUST call AsyncContext.complete()
if user application(AsyncListener or Error Page) does not call AsyncContext.complete().
This behavior is written in the explanation of AsyncContext in Servlet 3.0 specification, section 18.104.22.168 Asynchronous processing.
Any errors or exceptions that may occur during the execution of the dispatch methods MUST be caught and handled by the container as follows:
i.invoke the AsyncListener.onError(AsyncEvent) method for all instances of the AsyncListener registered with the ServletRequest for which the AsyncContext was created and make the caught Throwable available via the AsyncEvent.getThrowable()
ii. If none of the listeners called AsyncContext.complete or any of the AsyncContext.dispatch methods, then perform an error dispatch with a status code equal to HttpServletResponse.SC_INTERNAL_SERVER_ERROR and make the Throwable available as the value of the RequestDispatcher.ERROR_EXCEPTION request attribute.
iii.If no matching error page is found, or the error page does not call AsyncContext.complete() or any of the AsyncContext.dispatch methods, then the container MUST call AsyncContext.complete.
However, glassfish seems not to call AsyncContext.complete() if AsyncLister.onError() or Error Page does not call AsyncContext.complete().
Therefore, my sample application always waits until async timeout(glassfish default 30 seconds).
In addition, glassfish does not call complete() in case of async timeout of dispatch().
But if I use start() method for async processing, complete() is called in case of async timeout.
Is this a bug?
Otherwise, is my understanding of the specification wrong?