I have a somewhat linear job set up in Spring Batch that consists of several steps. If, at any point, a single step fails, the job should fail.
The steps consist of a number of tasklets followed by a chunk-based step. I.e.:
If something goes wrong, the obvious thing to do is throw an Exception. Spring Batch will handle this and log everything. This behaviour, particularly printing the stack trace, is undesirable, and it would be better if the Job could be ended gracefully with the Status set to FAILED
.
The Tasklets currently set the ExitStatus
directly on the StepContribution
. They are also built using a flow (which wasn't ideal, but the steps continue unhindered otherwise). The issues can then be handled directly in the Tasklet.
However, we have no access to the StepContribution
in the chunk-based approach. We only have the StepExecution
. Using setExitStatus
does nothing here.
We are using the builders (JobBuilerFactory
and StepBuilderFactory
), not the XML setups.
@AfterStep
.StepContribution
.As far as I know, the only way to stop the job is to throw an exception. There was no other graceful way of telling Spring Batch "This job is done, it failed, go directly to Failed, do not pass GO, etc."
Although not a direct solution to the original problem, one can use the .exceptionHandler()
of a StepBuilder
to gain more control over the exceptions you throw, e.g. logging them.
public class LogAndRethrowExceptionHandler implements ExceptionHandler {
private static final Logger LOGGER = Logger.getLogger(...);
@Override
public void handleException(RepeatContext repeatContext, Throwable throwable) throws Throwable {
LOGGER.error(throwable.getMessage());
throw throwable;
}
}
This way you may, in theory, hide the stack traces produced by Spring Batch but still show the error messages.