AsyncContext and IllegalStateException

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

AsyncContext and IllegalStateException

cp7781
Alright, following situation: There is a servlet, which starts an javax.servlet.AsyncContext. Inside that context several requests to a database are made, a java.awt.image.BufferedImage is painted and send back as a .png image response. It all works very well in the browser, even if the F5 key keeps being pressed.

It even works good, if a basic workload application is being utilized, which simulates 64 users reloading the diagram constantly.

But here comes the exception: If the workload application is being canceled manually via the NetBeans IDE, it causes major trouble on the server side. The Tomcat 8.0.36 log shows messages like:



Code:
org.apache.catalina.connector.ClientAbortException




Code:
03-Aug-2016 14:43:51.566 INFO [http-nio-80-exec-36] org.apache.coyote.AbstractProcessor.setErrorState An error occurred in processing while on a non-container thread. The connection will be closed immediately




Code:
Exception in thread "http-nio-80-exec-36" java.lang.IllegalStateException: The request associated with the AsyncContext has already completed processing.



And after such an accident, the web application becomes unusable. It responds with HTTP status code 500 and needs to be restarted.

So, I'm trying to figure out, what to do to prevent that.

Here is the affected method:

[/code]    /**
     * Print an .png image to the servlet response
     */
    private void printPNGImage(BufferedImage bufferedImage) {
        String formatName = "png";
        response.setContentType("image/" + formatName);
        try (ServletOutputStream servletOutputStream = response.getOutputStream()) {
            if (servletOutputStream != null) {
                ImageIO.write(bufferedImage, formatName, servletOutputStream);
            }
        } catch (IOException ex) {
            String message = "Can not write to the servlet output stream.";
            LOGGER.log(Level.SEVERE, message, ex);
        } finally {
            context.complete();
        }
    }

Code:


Any ideas? Share them with me.