SpringBatch - Step no longer executing: Step already complete or not restartable
Asked Answered
F

2

12

I have a single step springbatch application. The job is as follows:

@Bean
public Job databaseCursorJob(@Qualifier("databaseCursorStep") Step exampleJobStep,
                             JobBuilderFactory jobBuilderFactory) {
    return jobBuilderFactory.get("databaseCursorJob")
            .incrementer(new RunIdIncrementer())
            .flow(exampleJobStep)
            .end()
            .build();
}

I start the job from a springboot application. This afternoon, I attempted to add a second step to the job. Essentially as follows:

@Bean
public Job databaseCursorJob(@Qualifier("databaseCursorStep") Step exampleJobStep,
                             JobBuilderFactory jobBuilderFactory) {
    return jobBuilderFactory.get("databaseCursorJob")
            .incrementer(new RunIdIncrementer())
            .flow(exampleJobStep).next(partitionStep())
            .end()
            .build();
}

In other words, just adding the "next(partitionStep()). However, ever since I did this, the job finishes without executing any step (see shell output below). In fact, even after removing the second step and going back to the original job, it refuses to execute the step. Before attempting to add the second step, I never once encountered this problem. I have gone so far as restarting my VM and it still skips the step. I am rather dead in the water until I resolved this. Grateful for any insights. thanks.

2020-09-01 14:49:00.260  INFO 6913 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8087 (http) with context path ''
2020-09-01 14:49:00.263  INFO 6913 --- [           main] f.p.r.Application    : Started Application in 7.752 seconds (JVM running for 9.092)
2020-09-01 14:49:00.268  INFO 6913 --- [           main] o.s.b.a.b.JobLauncherCommandLineRunner   : Running default command line with: []
2020-09-01 14:49:00.579  INFO 6913 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=databaseCursorJob]] launched with the following parameters: [{}]
2020-09-01 14:49:00.698  INFO 6913 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Step already complete or not restartable, so no action to execute: StepExecution: id=120, version=4, name=databaseCursorStep, status=COMPLETED, exitStatus=COMPLETED, readCount=1, filterCount=0, writeCount=1 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=2, rollbackCount=0, exitDescription=
2020-09-01 14:49:00.730  INFO 6913 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=databaseCursorJob]] completed with the following parameters: [{}] and the following status: [COMPLETED]
Freshman answered 1/9, 2020 at 19:13 Comment(5)
Does this answer your question? Spring Batch error (A Job Instance Already Exists) and RunIdIncrementer generates only onceHsining
@MahmoudBenHassine . Thanks for your suggestion. I think that is different (but I could be wrong). Why would the problem not go away after restarting the VM? I would think that the jobIDs would be reset after restarting the VM. Shouldn't it work at least once after each restart of VM?Freshman
Are you using a persistent job repository or an in-memory one? You are not passing any job parameters, so the hash of an empty set of parameters will be the same and you end up on the same job instance each time. The answers in the duplicate question suggest to either add a parameter as a discriminator between job instances or set allowStartIfComplete=true on the step. Both of them should fix your issue.Hsining
Hi @MahmoudBenHassine you were absolutely correct that the question you presented above answered my problem. I do indeed have a local H2 db I am using for job repository, and your insights cleared the issue up for me. In the immediate-term, I have wiped out the job instance info in the H2 DB (actually, I created a new H2 DB because I thought that would be cleaner). But you have already helped me solve my immediate problem. I am not sure how to give you credit for that and bring the post to "solved".Freshman
@MahmoudBenHassine In the longer-term, I need to use the solutions as presented by you above. I was taking the approach of using discriminating job params (like a timestamp) to keep this from happening in the future. However, I am having issue with my current job-launching setup to convert to pass jobparameters. However, I think that is a new post rather than adding to this one.Freshman
F
7

My issue was that my job had no way recover if there was an error or stuck in an unknown state. The step was not "already complete", it never completed. Its status was still "STARTED", and exit code "UNKNOWN" because it never exited. Anyway, my job repository is not in memory, but captured to a local DB, which is why it never resolved itself even after restarting VM (shame on me for not remembering this). So, I was able to fix by wiping out the job instance history, however that was a band-aid. I still have to fix my code to prevent it from happening again.

I also learned I could diagnose by examining the job repository in the database (its all there).

I really resolved this thanks Mr Hassine who responded above several times and pointed me in the right direction. The solution to prevent in the future is indeed addressed in the link he provided in his first response: Spring Batch error (A Job Instance Already Exists) and RunIdIncrementer generates only once

Freshman answered 3/9, 2020 at 11:33 Comment(1)
Glad to hear your solved your issue. Always happy to help!Hsining
G
3

I faced this error and I resolved it by allowing the step to run again

.allowStartIfComplete(true)

Add this while creating a step right before the build(); It might help.

Granular answered 19/6, 2023 at 12:19 Comment(1)
Thank you for this. I faced same issue and this information helped me.Helico

© 2022 - 2024 — McMap. All rights reserved.