Skip to content

Different behavior of JobExecutionDecider when using @Configuration or @AutoConfiguration / proxyBeanMethods=false #4429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ck-trigfb opened this issue Aug 9, 2023 · 2 comments
Labels
status: superseded Issues that are superseded by other issues

Comments

@ck-trigfb
Copy link

Bug description
When using @AutoConfiguration the JobExecutionDecider will behave different than when just using @Configuration. Because @AutoConfiguration is @Configuration(proxyBeanMethods=false) you will get the same result with that setting.

If I use @Configuration(proxyBeanMethods=true) I will get for my attached example the following order of my steps: step1, step2, step3.
If I use @Configuration(proxyBeanMethods=false) I only get : step1, step2. So the Flow seems to be ended after the JobExecutionDecider.

Environment
Spring Batch 5.0.2, Java Version: 17.0.6, H2-Database

Steps to reproduce
Run attached project first with @Configuration and after that with @AutoConfiguration instead.

Expected behavior
Same behavior in the order of the execution of the steps.

Minimal Complete Reproducible example
Sample attached.
autoconfissue.zip

@ck-trigfb ck-trigfb added status: waiting-for-triage Issues that we did not analyse yet type: bug labels Aug 9, 2023
@hpoettker
Copy link
Contributor

hpoettker commented Sep 30, 2023

Hi @ck-trigfb, you can disable proxying of bean methods for your configuration classes by either setting proxyBeanMethods=false or by using @AutoConfiguration. But then you need to make sure that you don't rely on the methods being proxied. In particular, you should not invoke @Bean annotated methods yourself. This isn't specific to Spring Batch but holds true for all Spring applications.

You use the following factory method for your job:

@Bean
Job myJob(JobExecutionDecider myDecider) {
  return new JobBuilder("myJob", jobRepository)
      incrementer(new RunIdIncrementer())
      start(step1())                
      next(myDecider).on("REPEAT").to(step2())
      from(myDecider).on("END").end()
      from(step2()).on("*").to(step3())
      end()
      build();
}

To see your expected sequence of steps, you rely on that the invocation of step2() will return the exact same object both times. Only then it is clear for Spring Batch, that to and from refer to the same step.

As step2() is itself annotated with @Bean, it will only be executed once if the bean methods are proxied. Otherwise your job factory method will invoke the unproxied method twice and receive two different steps.

If you want to disable the proxying (for whatever reason), you should stop calling other @Bean annotated methods yourself. Instead, you can e.g. inject the steps as parameters of the function.

@fmbenhassine
Copy link
Contributor

@ck-trigfb Thank you for reporting this issue and for providing an example.

While this seems to be due to a difference in the behaviour of the job execution decider, it is rather related to the proxying of bean definition methods which impacts the flow definition. In fact, step instances must be unique within a flow definition, and this was not clearly documented. When bean method proxying is disabled, calling the same step @Bean definition method twice (or more) produces different step instances. Therefore, the flow definition is incorrect. In that case, steps can be injected as parameters of the job/flow definition method, which should ensure their uniqueness. I tried this approach on the attached example and it produces the desired output.

As part of #4460, the reference documentation was updated with this important detail (see note "Step bean method proxying in flow definitions" in Controlling Step Flow. The samples in that same page were also updated to inject steps as parameters of job definition methods to avoid any confusion.

I am closing this issue as superseded by #4460, but feel free to add a comment if you need more support on this.

@fmbenhassine fmbenhassine added status: superseded Issues that are superseded by other issues and removed status: waiting-for-triage Issues that we did not analyse yet type: bug labels Apr 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: superseded Issues that are superseded by other issues
Projects
None yet
Development

No branches or pull requests

3 participants