spring-projects / spring-projects/spring-batch
improve JobParameters to Non ThreadLocal
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 3k
- Forks
- 2.5k
- Avg merge
- 6d 53m
- Merged PRs (30d)
- 3
Description
JobParameters are managed by org.springframework.batch.core.scope.context.SynchronizationManagerSupport#executionHolder using ThreadLocal, which prevents SpEL bindings (@Value("#{jobParameters['param']}")) from working correctly in other threads.
However, JobParameters are typically read-only and do not change during batch execution. In a multi-threaded step (TaskExecutor), this ThreadLocal management causes access to JobParameters within JobScope or StepScope beans to fail.
I’m not sure why JobParameters need to be managed within a ThreadLocal JobContext. Could JobParameters be modified to be non-ThreadLocal instead?
I’m using a class that encapsulates JobParameters. However, access to this class's fields fails when accessed within a JobScope (or StepScope) bean in a multi-threaded step.
encapsulates JobParameters
@JobScope
@Component
public class MyJobParameters {
@Value("#{jobParameters['firstParam']}")
private String firstParam;
@Value("#{jobParameters['secondParam']}")
private String secondParam;
public String getFirstParam() {
return firstParam;
}
public String getSecondParam() {
return secondParam;
}
}
failed (multi thread step)
public Step myMultiThreadStep() {
return new StepBuilder("chunkWorkingStep", jobRepository)
.<Sample, Sample>chunk(500, new ResourcelessTransactionManager())
.reader(myReader())
.processor(myProcessor())
.writer(myWriter())
.taskExecutor(taskExecutor())
.build();
}
public ItemProcessor<Sample, Sample> myProcessor() {
String firstParam = myJobParameters.getFirstParam(); // failed
return item -> {
String secondParam = myJobParameters.getSecondParam(); // failed
return item;
};
}
ok (non multi thread step)
public Step myStep() {
return new StepBuilder("chunkWorkingStep", jobRepository)
.<Sample, Sample>chunk(500, new ResourcelessTransactionManager())
.reader(myReader())
.processor(myProcessor())
.writer(myWriter())
.build();
}
public ItemProcessor<Sample, Sample> myProcessor() {
String firstParam = myJobParameters.getFirstParam(); // ok
return item -> {
String secondParam = myJobParameters.getSecondParam(); // ok
return item;
};
}
If there’s anything I might be missing or not understanding, please let me know.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with org.springframework.batch.core.scope.context.SynchronizationManagerSupport#executionHolder and trace how JobParameters are resolved for JobScope and StepScope beans. Reproduce the supplied multi-threaded-step example, then define tests showing that SpEL JobParameters bindings remain available across worker threads without breaking existing scope behavior.
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
- Needs clarification
- Newbie friendliness
- 25/100