views:

346

answers:

2

I have a web application that makes use of a Spring TaskExecutor. The task executor is started when the web application is loaded for the first time and the thread runs the entire life of the web application. Ever since I added this thread to the application, Oracle Application Server will no longer shutdown gracefully. My guess is that OAS is not shutting down because I am not gracefully shutting down the task executor thread anywhere in the code. Where would the best place be to shutdown the task executor in a web application? I am using Java 5 with Spring 2.5.6.

Here is the task executor that I am using:

<bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
+1  A: 

SimpleAsyncTaskExecutor has no meaningful state, it does not require shutting down gracefully. Also, I'm not sure what you mean by "the thread runs the entire life of the web application" - which thread are you referring to?

However, the threads that it spawns may be preventing your server from shutting down. SimpleAsyncTaskExecutor uses a ThreadFactory to create its threads, and by default threads that are created are not daemon threads, and so any spawned threads which are still executing when the shutdown is initiated will continue, and the server will only terminate when all of those spawned threads are finished.

As a solution, I suggest using a ThreadPoolTaskExecutor in preference to the SimpleAsyncTaskExecutor. This has a boolean property which controls what happens when a shutdown occurs, and it can force the termination of the thread pool if required.

If you still want to use SimpleAsyncTaskExecutor, then you could inject it with a custom ThreadFactory which creates deamon threads. This will allow the server to shutdown regardless of the state of those spawned threads. This might be dangerous, though, if those threads could leave resources in an unstable state.

Spring provides a bean-friendly implementation of ThreadFactory (CustomizableThreadFactory) which you can inject into the SimpleAsyncTaskExecutor, setting the daemon property to false.

skaffman
I'll give that a shot. What I mean about "the thread runs the entire life of the web application" is that when the Spring context is loaded, I use the task executor to spawn one thread, which is a consumer. This thread is the only thread that is ever created by the executor and it runs until the web server is shutdown.
hoffmandirt
Ah, that's the problem then - that thread won't wait until the server shuts down, the server will wait for *it* to shut down.
skaffman
A: 

Typically web aplications can react to container shutdown via a ServletContextListener. Implement one and use it to shut down your Executor. Ideally you should couple that with a proper shutdown of the whole Spring lifecycle. I vaguely remember that Spring had something ready-made for that purpose, so it's probably a good idea to check there as well.

Holger Hoffstätte
Thanks. Spring has the ApplicationListener interface. Any idea how I can cancel the block on a LinkedBlockingQueue.take()? I tried myQueue.notifyAll().
hoffmandirt
My standard answer to that is "never use blocking waits, ever, anywhere". Alternatively inject a special object known as "poison pill" or interrupt the thread, as suggested in http://stackoverflow.com/questions/812342/how-to-interrupt-a-blockingqueue-which-is-blocking-on-take
Holger Hoffstätte