This post is part of a series delving into the details of the JSR-352 (Java Batch) specification. Each post examines a very specific part of the specification and looks at how it works and how you might use it in a real batch application.
To start at the beginning, follow the link to the first post.
The next post in the series is here.
Last time we were talking about making decisions in the flow of a job using a Decision element in the JSL which executes an implementation of the Decider interface. That Decider gets passed as a parameter an array of StepExecution objects. This time we’ll take a peek inside the StepExecution object and ponder why you might get an array of them.
A StepExecution is a little like a StepContext. It has information about a step like the step name, when it started and ended, and what the Batch and Exit Status values were. Well, that’s fine…which step’s StepExecution object gets passed to the Decider?
That’s where it gets tricky. In general, the Decider gets passed the StepExecution object from the step that preceded it. If you have a simple step that runs a batchlet and then flows to a Decider, the Decider will get the StepExecution object from that batchlet step. In essence, here’s how this step ended, now decide what to do.
The parameter is an array because more than one thing might flow to a Decider at the same time. Suppose you have a Split with several Flows. The next attribute on the Split can point to a Decision element. That Decider will get control with the array containing StepExecution objects for the final step of each Flow within the Split. That allows you to decide what to do next based on how all the Flows turned out.
The StepExecution also contains the Persistent User Data from the Step. Remember that persistent data has to be serializable. This allows the previous step (or the final step in each flow of a split) to pass an entire object to the Decider. Which can be a huge help as the Decider tries to figure out what to do.
Let’s wrap this up then…a Decider can get control after previous things have executed in the job, whether that previous thing is a simple step, a flow, or several flows within a split. The Decider gets information about all the Steps that ran just prior to it, even if there are more than one of them across several concurrent threads. That information includes the Persistent User Data from those Steps. The Decider can set an Exit Status that can be used for flow control within the job AND also sets the Exit Status for the job itself (unless something later on overrides it).
Pretty powerful stuff.