May 26th, 2008, 06:18 AM
Exception in asynchronous SimpleJobLauncher
I am using the SimpleJobLauncher with an asynchronous taskExecutor, so that my starter gets a reference to the jobExecution immediately and can possibly stop it, while the job runs on another thread. This works fine, except for the following :
When a fatal exception is thrown by the Job.execute() method, the thread dies with a stack trace and the exception does not reach the caller of the job launcher, and the JobExecution is never updated, so that the batch starter is never aware of a problem.
I have overpassed this issue by writing my own JobLauncher, by coying your code, except for the rethrow() method, which is not invoked. I am storing the exception is a context that is shared between the job launcher and the caller of the job launcher, so this object is aware of a fatal problem.
This works, but the only problem resides in the creation of this shared context, which is currently a static object, which I do not like. Is there a better way to do this ? (IMO, the ideal solution would be to store the exception in the JobExecution, as this object is available on both the job launcher and the job starter, but I do not want to write my own JobRepository, JobDao, etc).
May 27th, 2008, 02:06 AM
What kind of exception is not propagated and stored in the JobExecution? The ExitStatus should give you everything you need to know. N.B. there was a potential problem in this scenario with visibility of changes to the JobExecution across threads (http://jira.springframework.org/browse/BATCH-603), which might be affecting you. I believe (though I haven't tested because it never affected me) you should be able to get the information from the step execution inside your job execution in any case, but I would be interested to know if the latest snapshot from 1.1 works for you without resorting to that.
May 27th, 2008, 07:18 AM
You are right : even if job.execute() fails and throws an exception, an exit status that's usable is stored in jobExecution.
The problem is then more "cosmetic": if the SimpleJobLauncher is configured with an asynchronous taskExecutor, a caught exception in job.execute() is rethrown in the TaskExecutor's Runnable, which then kills the Executor's thread and prints a stack trace on the error console, which frightens the operators.