spring-projects / spring-projects/spring-batch

Add ability to pass values from JobExecution context to calling JobStep execution context

Open
#4,524 2 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage type: feature
Dominant language
Java
Stars
3k
Forks
2.5k
Avg merge
6d 53m
Merged PRs (30d)
3

Description

This request comes from the Stack Overflow question posed here:
https://stackoverflow.com/questions/77649370/promote-execution-context-from-jobstep-to-calling-step

When using a JobStep, there is no means to pass values from the execution context of the child job run in the JobStep back to the parent step, similar to how an ExecutionContextPromotionListener would be used to promote values from a child step back up to the parent job. This cannot be achieved in the current design, in part, because the JobExecution of the job being called is only scoped to the JobStep.doExecute method.

It would be nice to have an interface that specified actions to be performed between the child JobExecution and parent StepExecution. The JobStep.determineStepExitStatus method is one example of code that could implement this interface and the Job to Step Execution Context Promotion would be another example.

Background:

I'm developing a small report-running framework to add to an application that uses Spring Batch for a number of integration tasks. The design consists of three steps:

  1. Retrieve a Report Definition from a database table (contains a Job Name, static parameters to pass to job, list of users who receive the report) and put that into the Step/Job Execution Context. This step is accomplished via a tasklet.
  2. Use the Report Definition in the Execution context to create a JobStep. The job would perform whatever logic that needs to be done and creates a file. The name of this file would be provided in the child job's execution context to be passed to the next step in the parent job.
  3. Distribute that file out to the users (probably another tasklet).

Here's what the second step currently looks like, pre-workaround mentioned below:

@JobScope
@Bean(name="runReportStep")
Step buildRunReportStep(@Value("#{jobExecutionContext['reportDefn']}") ReportDefinition rptDfn) {
        try {
            Job job = jobRegistry.getJob(rptDfn.getJobName());
            return new StepBuilder("runReportStep", jobRepository)
                                               .job(job)
                                               .launcher(jobLauncher)
                                               .build();
        } catch (NoSuchJobException e) {
            return null;
        }
}

Alternatives considered:

  • Use an external data store (database table) to store the information.
  • Subclass JobScope, copying the doExecute method and rewriting the determineStepExitStatus to also perform the task of JobExectution -> StepExecution promotion. This is the approach I am currently using as a workaround

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading JobStep.doExecute and determineStepExitStatus, then compare their lifecycle with ExecutionContextPromotionListener. The proposed interface should cover actions between the child JobExecution and parent StepExecution, including context promotion; done means the parent step can receive selected child context values without the described JobScope workaround.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.