Accessing Job Parameters Spring Batch
Solution 1
Another solution that works very well for ItemProcessors, ItemReaders, ItemWriters and so on is the @BeforeStep annotation. It is backed by a StepExecutionListener just like Eugene To mentioned. It is kind of a shortcut for that solution.
An implementation might look like this
@BeforeStep
public void beforeStep(StepExecution stepExecution) {
JobParameters jobParameters = stepExecution.getJobParameters();
Long millis = jobParameters.getLong("time");
String path = jobParameters.getString("filePath");
}
Solution 2
You should be able to do ,
@Value("#{jobParameters['filePath']}") String filePath;
In case of any issues, you may try putting your reader in @StepScope
.
Solution 3
You may add org.springframework.batch.core.listener.JobParameterExecutionContextCopyListener
to your Step.
TaskletStep step = stepBuilderFactory.get("my-best-step")
.<Item, Item>chunk(10)
.reader(myBestReader)
.writer(myBestWriter)
.listener(new JobParameterExecutionContextCopyListener())
.build();
That Listener will copy JobParameters
to ExecutionContext
that is available in ItemReader's open and update methods
Related videos on Youtube
Deepak Puthraya
I am currently working as Senior Software Engineer at Playment. I enjoying coding in Java, Golang, JavaScript and Python.
Updated on September 15, 2022Comments
-
Deepak Puthraya over 1 year
I have been struggling with accessing Job Parameters of a job using spring batch. Here is my implementation so far.
@Configuration @EnableBatchProcessing @PropertySource("classpath:batch.properties") public class CSVBatchServiceImpl extends StepExecutionListenerSupport implements CSVBatchService { private static final Logger LOGGER = LoggerFactory.getLogger(CSVBatchServiceImpl.class); @Autowired public JobBuilderFactory jobBuilderFactory; @Autowired public StepBuilderFactory stepBuilderFactory; private QuestionReader questionReader = new QuestionReader(); @Bean(name = "importQuestionsJob") public Job importQuestionsJob() { return jobBuilderFactory.get("importQuestionsJob") .incrementer(new RunIdIncrementer()) .flow(step1()) .end() .build(); } @Bean public Step step1() { return stepBuilderFactory.get("step1") .<Question, Question>chunk(2) .reader(questionReader.reader()) .processor(processor()) .build(); } @Bean public QuestionProcessor processor() { return new QuestionProcessor(); } } class QuestionReader extends StepExecutionListenerSupport { private static final Logger LOGGER = LoggerFactory.getLogger(QuestionReader.class); //TODO: remove this private static JsonNode getJsonNode(String str) { try { ObjectMapper mapper = new ObjectMapper(); return mapper.readTree(str); } catch (IOException e) { throw new RuntimeException(e); } } @Bean public FlatFileItemReader<Question> reader() { FlatFileItemReader<Question> reader = new FlatFileItemReader<>(); //TODO get this as a parameter reader.setResource(new ClassPathResource("duplicateLabels.csv")); reader.setLinesToSkip(1); reader.setLineMapper(new DefaultLineMapper<Question>() {{ setLineTokenizer((new DelimitedLineTokenizer() {{ setNames(new String[]{"label", "body", "real_answer"}); }})); setFieldSetMapper(new QuestionFieldSetMapper()); }}); return reader; } private static class QuestionFieldSetMapper implements FieldSetMapper<Question> { public Question mapFieldSet(FieldSet fieldSet) { Question question = new Question(); question.setLabel(fieldSet.readString(0)); question.setBody(getJsonNode(fieldSet.readString(1))); question.setRealAnswer(getJsonNode(fieldSet.readString(2))); return question; } } }
I am calling the job like:
JobParameters parameters = new JobParametersBuilder() .addLong("time", System.currentTimeMillis()) .addString("filePath", "file.csv") .toJobParameters(); jobLauncher.run(importQuestionsJob, parameters);
How can I go about accessing the filePath parameter inside reader function?
-
M. Deinum about 7 yearsSetting a scope is mandatory using this without it will not work.
-
Deepak Puthraya about 7 yearsWould really appreciate if you could tell me where I could add in code.
-
Sabir Khan about 7 yearsI guess, you need it in
reader()
method so you can change reader signature like ,reader(@Value("#{jobParameters['filePath']}") String filePath)
but make sure that you annotatereader
with@StepScope
. In your step definition, you can passnull
for this parameter like ,questionReader.reader(null)
.