Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get access to job parameters from ItemReader, in Spring Batch?

This is part of my job.xml:

<job id="foo" job-repository="job-repository">   <step id="bar">     <tasklet transaction-manager="transaction-manager">       <chunk commit-interval="1"         reader="foo-reader" writer="foo-writer"       />     </tasklet>   </step> </job> 

This is the item reader:

import org.springframework.batch.item.ItemReader; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component("foo-reader") public final class MyReader implements ItemReader<MyData> {   @Override   public MyData read() throws Exception {     //...   }   @Value("#{jobParameters['fileName']}")   public void setFileName(final String name) {     //...   } } 

This is what Spring Batch is saying in runtime:

Field or property 'jobParameters' cannot be found on object of  type 'org.springframework.beans.factory.config.BeanExpressionContext' 

What's wrong here? Where I can read more about these mechanisms in Spring 3.0?

like image 962
yegor256 Avatar asked May 20 '11 22:05

yegor256


People also ask

How do I access JobParameters in Spring Batch?

JobParameters can be used for identification or even as reference data during the job run. They have reserved names, so to access them we can use Spring Expression Language. For example to access a property 'abc' on job parameters: we can access it using the syntax #{jobParameters[abc]} .

How do I run a specific job in Spring Batch?

Spring Batch auto configuration is enabled by adding @EnableBatchProcessing (from Spring Batch) somewhere in your context. By default it executes all Jobs in the application context on startup (see JobLauncherCommandLineRunner for details). You can narrow down to a specific job or jobs by specifying spring. batch.

What is StepExecution in Spring Batch?

public class StepExecution extends Entity. Batch domain object representation the execution of a step. Unlike JobExecution , there are additional properties related the processing of items such as commit count, etc.

What is JobExplorer in Spring Batch?

public interface JobExplorer. Entry point for browsing executions of running or historical jobs and steps.


2 Answers

As was stated, your reader needs to be 'step' scoped. You can accomplish this via the @Scope("step") annotation. It should work for you if you add that annotation to your reader, like the following:

import org.springframework.batch.item.ItemReader; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;  @Component("foo-reader") @Scope("step") public final class MyReader implements ItemReader<MyData> {   @Override   public MyData read() throws Exception {     //...   }    @Value("#{jobParameters['fileName']}")   public void setFileName(final String name) {     //...   } } 

This scope is not available by default, but will be if you are using the batch XML namespace. If you are not, adding the following to your Spring configuration will make the scope available, per the Spring Batch documentation:

<bean class="org.springframework.batch.core.scope.StepScope" /> 
like image 50
Sean Kleinjung Avatar answered Sep 21 '22 11:09

Sean Kleinjung


If you want to define your ItemReader instance and your Step instance in a single JavaConfig class. You can use the @StepScope and the @Value annotations such as:

@Configuration public class ContributionCardBatchConfiguration {     private static final String WILL_BE_INJECTED = null;     @Bean    @StepScope    public FlatFileItemReader<ContributionCard> contributionCardReader(@Value("#{jobParameters['fileName']}")String contributionCardCsvFileName){       ....    }     @Bean    Step ingestContributionCardStep(ItemReader<ContributionCard> reader){          return stepBuilderFactory.get("ingestContributionCardStep")                  .<ContributionCard, ContributionCard>chunk(1)                  .reader(contributionCardReader(WILL_BE_INJECTED))                  .writer(contributionCardWriter())                  .build();     } } 

The trick is to pass a null value to the itemReader since it will be injected through the @Value("#{jobParameters['fileName']}") annotation.

Thanks to Tobias Flohre for his article : Spring Batch 2.2 – JavaConfig Part 2: JobParameters, ExecutionContext and StepScope

like image 28
Ortomala Lokni Avatar answered Sep 19 '22 11:09

Ortomala Lokni