1

My batch job is configured as follows

@Bean("MyJob")
    public Job umpInpatientCensusRptBatchJob(...) throws IOException {
        return jobBuilderFactory.get( "MyJob" )
                .incrementer( new RunIdIncrementer() )
                .start( Step0 ).on( COMPLETE ).end()
                .from( Step0 ).on( CONTINUE )
                .to( Step1 )
                .next( Step2 )
                .next( Step3 )
                .end()
                .build();
    }

where Steps 0, 1, and 3 are tasklets. My Job is completing with the message Job: [FlowJob: [name=MyJob]] completed with the following parameters. However, it doesn't exit - it hangs there. When I run it locally on IntelliJ, I have to manually quit the job.

I haven't implemented any asynchronicity. Each tasklet is also explicitly returning a FINISHED status upon completion.

1 Answers1

2

An apparent problem is the word "COMPLETE" inside the first on(). The method on(String pattern) is given "COMPLETE" as a parameter instead of, for example, "COMPLETED", the job completes with a FAILED state, if an appropriate custom exit status hasn't been created. However, I don't know why it hangs and doesn't just fail in your case. The following version of your job configuration seems to run fine, as long as all the tasklets return a FINISHED RepeatStatus:

@Bean("MyJob")
public Job umpInpatientCensusRptBatchJob(...) throws IOException {
    return jobBuilderFactory.get( "MyJob" )
            .incrementer( new RunIdIncrementer() )
            .start( Step0 ).on( "COMPLETED" ).end()
            .from( Step0 ).on( "CONTINUE" )
            .to( Step1 )
            .next( Step2 )
            .next( Step3 )
            .end()
            .build();
}

If the tasklet of Step0 returns RepeatStatus.CONTINUABLE though, Step0 repeats forever, since that is the purpose of that RepeatStatus. So, it's impossible to reach Step1 with this configuration. In order to decide if you should run the next steps, instead of using the tasklet repeat status (which I don't know if is possible) you could either use a StepExecutionListener on Step0 or add a decider to the flow, after Step0:

Spring-Batch: how do I return a custom Job exit STATUS from a StepListener to decide next step

  • Hey - I'm circling back to this problem (doing away with the System.exit statement to terminate the job). I noticed that the COMPLETE status is working fine, i.e. if the tasklet returns a COMPLETE, the job ends. It's when it returns a CONTINUE that that the job hangs even after it completes – TheLifeOfParallax Mar 20 '20 at 16:47
  • I think when Step0 returns CONTINUE, the job doesn't consider that step to be complete? – TheLifeOfParallax Mar 20 '20 at 16:51
  • Regardless if the step is complete or not, if the configuration says .on(CONTINUE).to(Step1), then Step1 should start whenever Step0 has a CONTINUE status. – Atium Addict Mar 20 '20 at 17:00
  • Yes, that logic indeed gets executed. If Step0 returns COMPLETE, then the job ends successfully. However, if Step0 returns CONTINUE, the job performs all of the correct next steps, but hangs after completion. – TheLifeOfParallax Mar 20 '20 at 17:08
  • I think the flow fails to terminate in the CONTINUE branch – TheLifeOfParallax Mar 20 '20 at 17:23
  • Yeah, sorry, you're right. That's also what I wrote in my initial answer. The only 2 possible repeat statuses of a tasklet are FINISHED and CONTINUABLE. COMPLETED means that the tasklet doesn't need to re-execute, while CONTINUE means that the tasklet needs to be repeated. So, unless the execute method tasklet returns COMPLETED at some point, the job cannot be completed. I think the way to do what you want, as I wrote in my initial answer, is to update a value in the JobExecutionContext from the tasklet, which can be used in a decider in order to end the job or move on to the next step. – Atium Addict Mar 21 '20 at 19:55