Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are non-container thread errors in tomcat?

In catalina.out log of my Tomcat7 I get an error caused by a third-party library that starts with:

INFO: An error occurred in processing while on a non-container thread. The connection will be closed immediately
java.net.SocketException: Broken pipe
        at java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)

What does it really mean that the error occurred in a non-container thread?

I tried to get a similar log message by throwing an a exception from a new Thread spawned from my application code with something like that:

new Thread(){
    @Override
    public void run() {
        Integer.parseInt("boom");
    }
}.start();

but it results in

Exception in thread "Thread-28" java.lang.NumberFormatException: For input string: "boom"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:492)
    at java.lang.Integer.parseInt(Integer.java:527)
    at ...

So the question is: What does it mean when I see a log like the one quoted on the top? What does it mean that the error occurs in a non-container thread? How can I recreate that?

like image 739
TMG Avatar asked May 05 '16 22:05

TMG


Video Answer


1 Answers

What does it really mean that the error occurred in a non-container thread?

This happens when you are using JSP 3.0+ asynchronous request processing.

In asynchronous mode, the client request is received by a "container" thread that calls the Servlet's service() method. This method (or one of the subsidiary doXxxx methods) calls startAsync() which creates a Runnable for the request and dispatches it to an Executor. This executor then processes the requests on ("non-container") worker threads.

(A more detailed explanation of what is going on in async mode, complete with an example, can be found here.)

Anyhow, the "INFO:" message is simply saying that the original exception was thrown on the stack of one of the Executor's worker threads. It is produced when Tomcat decides to dispatch the failed request back to a a container thread so that the request cleanup can be performed.

In your example, I suspect that the original SocketException was caused by the request processing taking so long that the client (e.g. the user's browser) timed out the request and closed the socket. Some time later, your server tried to write the response and that failed because the connection had been closed.

How can I recreate that?

I am guessing, but you should be able to reproduce that "INFO:" message by throwing an exception in the Runnable's run() method. You have to use async mode of course.

like image 190
Stephen C Avatar answered Sep 22 '22 22:09

Stephen C