spring-projects / spring-batch

Spring Batch is a framework for writing batch applications using Java and Spring
http://projects.spring.io/spring-batch/
Apache License 2.0
2.73k stars 2.35k forks source link

Conditional Flow does not work as stated in official documentation #4153

Open m4rcc opened 2 years ago

m4rcc commented 2 years ago

The conditional flow does not work as stated in the official documentation (https://docs.spring.io/spring-batch/docs/current/reference/html/step.html#controllingStepFlow)

Tried with: Spring Boot: 2.6.7 >> 4.3.5</spring-batch.version> >> Java8 Spring Boot: 2.6.9 >> 4.3.6</spring-batch.version> >> Java8

@Bean
public Job job() {
    return this.jobBuilderFactory.get("job")
                .start(stepA())
                .on("*").to(stepB())
                .from(stepA()).on("FAILED").to(stepC())
                .end()
                .build();
}

If I use the above example, then:

stepA() is completed successfully then it runs ok to stepB() >> as expected stepA() fails then step stepB() is executed >> expected stepC() to be executed but instead it was again stepB()

If I reverse the order:

@Bean
public Job job() {
    return this.jobBuilderFactory.get("job")
                .start(stepA())
                                 .on("FAILED").to(stepC())
                .from(stepA()).on("*").to(stepB())
                .end()
                .build();
}

Then I get the following results:

stepA() is completed successfully then it throws Flow execution ended unexpectedly ... Next state not found in flow=... for state=job.step0 with exit status=COMPLETED stepA() fails then step stepC() is executed >> as expected

The above code was to simplify the explanation, I have attached the example I used. I simulated FAILURE in the first step by throwing an error from FirstItemReader.

Could this be a regression of https://github.com/spring-projects/spring-batch/issues/3638

Also, what is the difference between, is the latter a valid Flow syntax?:

@Bean
public Job job() {
    return this.jobBuilderFactory.get("job")
                .start(stepA()).on("*").to(stepB())
                .from(stepA()).on("FAILED").to(stepC())
                .end()
                .build();
}

and:

@Bean
public Job job() {
    return this.jobBuilderFactory.get("job")
                .start(stepA()).on("*").to(stepB()).end();
                .start(stepA()).on("FAILED").to(stepC()).end()
                .build();
}

Thank you

spring-batch-demo.zip

MartijnKruissen commented 2 years ago

I've noticed similar behavior regarding unexpected transitions. I've debugged it down to the change in FlowBuilder.java between spring-batch-core 4.2.4 and 4.2.5. In 4.2.4 the step name is used to create the name for the state. This creates consistent transitions. in 4.2.5 a counter is used to create the name. Due to an incorrect increment an invalid transition is created.

For a local fix I've added FlowBuilder version 4.2.4 in our code and use that as the flowbuilder.

Below is an image of the same transitions generated by the two versions. The left one is correct. The right one fails with a "flow execution ended unexpectedly".

transitions_424_425

cmarcu55 commented 2 years ago

Hi, Is there any plan for this bug to be fixed?

suchins3 commented 1 year ago

HI, We also face the same issue. Can you please look in to the same

fmbenhassine commented 1 year ago

Thank you for opening this issue. We do not exclude that this could be a bug in Spring Batch. However, we would like to validate that with a minimal complete verifiable example.

Could you please take some time to create a minimal example that reproduces the problem? To help you in reporting your issue, we have prepared a project template that you can use as a starting point. Please check the Issue Reporting Guidelines for more details about this.

Thank you for your collaboration.