Skip to content
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

Allow Lambdas to be passed as item processors in Java DSL #4061

Closed
hpoettker opened this issue Feb 11, 2022 · 4 comments
Closed

Allow Lambdas to be passed as item processors in Java DSL #4061

hpoettker opened this issue Feb 11, 2022 · 4 comments
Labels
Milestone

Comments

@hpoettker
Copy link
Contributor

Status quo in Spring Batch 4.x

In Spring Batch 4.x, it is not possible to pass a lambda or method reference to SimpleStepBuilder::processor.

The method is overloaded to accept either an ItemProcessor or a Function, which both qualify as functional interfaces. This makes passing a lambda ambivalent if it is not explicitly cast to one of the two. In my opinion, the casts that need to be applied to pass lambdas are unnecessarily ceremonial and feel clunky in modern Java that strongly favors lambdas over explicit Function.

In other words, it would be great if one could write

stepBuilderFactory.get("multiplyBy2Step")
  .<Integer, Integer>chunk(chunkSize)
  .reader(itemReader())
  .processor(i -> i * 2)
  .writer(itemWriter())
  .build();

instead of either

stepBuilderFactory.get("multiplyBy2Step")
  .<Integer, Integer>chunk(chunkSize)
  .reader(itemReader())
  .processor((ItemProcessor<Integer, Integer>) i -> i * 2)
  .writer(itemWriter())
  .build();

or

stepBuilderFactory.get("multiplyBy2Step")
  .<Integer, Integer>chunk(chunkSize)
  .reader(itemReader())
  .processor((Function<Integer, Integer>) i -> i * 2)
  .writer(itemWriter())
  .build();

Feature request for Spring Batch 5.0

To allow lambdas and method references to be passed directly to SimpleStepBuilder::processor, please consider to drop the possibility to pass Function. If the method only accepted ItemProcessor, passing a lambda would not be ambivalent and not require a cast.

This is a breaking change in a central DSL but I think Spring Batch 5.0 is the perfect moment to do this.

From my perspective, most applications would need to simply drop casts to Function to migrate from 4.x to 5.0. Applications that do use actual Function objects as arguments for SimpleStepBuilder::processor would need to replace code like

stepBuilderFactory.get("step")
  .<Integer, Integer>chunk(chunkSize)
  .reader(itemReader())
  .processor(function)
  .writer(itemWriter())
  .build();

with

stepBuilderFactory.get("step")
  .<Integer, Integer>chunk(chunkSize)
  .reader(itemReader())
  .processor(function::apply)
  .writer(itemWriter())
  .build();

for a straight-forward migration approach.

@hpoettker
Copy link
Contributor Author

The milestone release 5.0.0-M2 is due shortly and, up to now, this issue has not sparked the interest that I expected.

Is the proposal too aggressive? An alternative is to now declare the possibility to use a Function in the DSL as deprecated for removal in release 5.1, and remove it then.

In my opinion, this issue should really not be deferred to Spring Batch 6. Assuming that the release cadences of the Java ecosystem stay constant, this would lead to a situation where Spring Batch offers idiomatic support for a Java 8 feature (i.e. lambdas) only after the release of Java 29.

@hpoettker
Copy link
Contributor Author

hpoettker commented Mar 29, 2022

Still trying to summon support for this one! 😄

At least two past issues support my case: #3749 and #3880.

Both problem descriptions contain a cast lambda being passed to processor(), and the underlying bug could only exist because the lambda takes different code paths depending on whether it is cast to an ItemProcessor or a Function although there is no intended difference in functionality.

In my opinion, these separate code paths make the step DSL unnecessarily hard to reason about. And as elaborated in the original post, I don't see that the code path for Function really adds that much value.

@fmbenhassine fmbenhassine added in: core and removed status: waiting-for-triage Issues that we did not analyse yet labels Apr 1, 2022
@fmbenhassine fmbenhassine added this to the 5.0.0 milestone Apr 1, 2022
@fmbenhassine fmbenhassine added the has: votes Issues that have votes label Apr 29, 2022
@fmbenhassine
Copy link
Contributor

I agree that the cast is verbose and that this issue should not be deferred to v6.

Is the proposal too aggressive? An alternative is to now declare the possibility to use a Function in the DSL as deprecated for removal in release 5.1, and remove it then.

For consistency, we typically follow the same policy as Spring Boot for deprecations. This means if we deprecate the overloaded method in v5.0, we would only remove it in v5.2, not in v5.1. It is always aggressive to remove a public API without deprecation, but I think we can make the exception in a major version like v5, especially that the migration approach you suggested is straight-forward. That said and based on the current yearly-based release cadence of Spring Batch for minor versions, I see no need to keep this overloaded method (and afflict the ceremonial cast to our users) for at least two years from v5 GA date, so I will plan #4062 for 5.0.0-M3.

However, I disagree on the removal of FunctionItemProcessor as in #4062. This component can be kept in the library provided by Spring Batch, which can be enriched with similar functional components in a future release. These components would be similar to those in the library of adapters, but are not reflection-based (which could impact the performance when processing large data sets).

@fmbenhassine fmbenhassine modified the milestones: 5.0.0, 5.0.0-M3 Apr 29, 2022
@hpoettker
Copy link
Contributor Author

@benas Thanks! That's great news.

I've reverted the removal of the FunctionItemProcessor from the PR.

@fmbenhassine fmbenhassine changed the title Allow Lambdas to be passed as Processors in Java DSL Allow Lambdas to be passed as item processors in Java DSL May 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants