Aug 29th, 2007, 08:42 AM
TaskExecutorRepeatTemplate/ThreadPoolTaskExecutor: Threads hung if misconfigured
I just wanted to post a problem and a solution to a problem / misconfiguration-related issue with the TaskExecutorRepeatTemplate, or actually the underlying ThreadPoolTaskExecutor.
If the TaskExecutorRepeatTemplate is mis-configured then Thread Pool threads will hang up the execution (i.e. never finish, waiting for more data to be processed).
This can be solved by adding a destroy-method="shutdown" to the ThreadPoolTaskExecutor bean configuration. But also take into account that Spring will NOT AUTOMATICALLY DESTROY THE BEAN unless you explicitly call the destroy() method of the DisposableBean (i.e. a ClassPathXmlApplicationContext) in your main method.
Another 'gotcha' is that the destroy-method will ONLY be called if the bean is a top-level bean. If it is a nested bean, then Spring (core) does not call it's shutdown method (don't know if this is a Spring bug or not).
Hope this Helps
Aug 29th, 2007, 10:33 AM
Actually the destroy method is called when the bean's lifecycle ends. That should be automatic in most cases (but your mileage may vary - e.g. if you are using kill -9 or something to end a process). The application context generally is closed on a JVM shutdown hook, if in no other place, and that triggers the end of life for all its beans.
This might be a good use of scope="step" as well, since then you will get the destroy callback at the end of the step execution.
Aug 29th, 2007, 12:14 PM
And what should I put the scope 'step' to? The taskexecutor?
Regarding the JVM hook, I understand that is the way it works, but I do not want the Operator to terminate the 'fast run' batch with CTRL+C, and it will also not work in the case of a Cron Scheduler, since the program will never end because of the hang threads.
Could you elaborate on the 'step' scope so I can try it out?
Aug 29th, 2007, 03:30 PM
In a nutshell: you can make anything step scoped that needs to have a lifecycle tied to the step execution. The StepExecutor is responsible for making sure that the scope is created and destroyed at the beginning and end of the step (which it delegates to StepSynchronizationManager, a bit like a TransactionSynchronizationManager). Along with the scope context your beans will get the usual Spring lifecycle callbacks (init, destroy, post processors etc. - all the good stuff).
Sorry - the step scope docs are a bit thin on the ground right now. The Javadocs get you some of the way, and the samples probably get you some more. But we really need some quality user reference docs (c.f. http://opensource.atlassian.com/proj...owse/BATCH-120). There are also a couple of irritating bugs in Spring Core right now that make it slightly more painful to use and to explain (SPR-3800, SPR-3804). They should be fixed soon.
So you should be able to rely on it for your use case with either TaskExecutor or its parent (if it is an inner bean). Remember to mark dependencies as <aop:scoped-proxy>. And bear in mind that inner beans won't work until SPR-3800 is fixed (yes, that contradicts the last sentence, but it's a short term situation).