0

I am launching a spring batch Job from my controller. I need to access the job parameter fileName from configured custom ItemReader via java based configuration.But I always gets the fileName as null from my ItemReader. Please help. I am launching like this because I have to change ItemReader file according to the user request.

My Controller :

@RestController
@RequestMapping(value = "/")
public class SimpleController {


@Autowired
Step step;

@Autowired
private JobBuilderFactory jobs;

@Autowired
private StepBuilderFactory steps;

@Autowired
private JobRepository jobRepository;

@Autowired
JobLauncher jobLauncher;

@RequestMapping(method = RequestMethod.GET)
public void StartJob() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
    JobParameter param = new JobParameter("ValueBeingSetFromRequestHeader");
    HashMap map = new HashMap<String, JobParameter>();
    map.put("fileName",param);
    SimpleJob job = new SimpleJob("test");
    job.addStep(step);
    System.out.println(jobRepository);
    job.setJobRepository(jobRepository);

    System.out.println( jobRepository.getLastJobExecution(job.getName(), new JobParameters(map)));

    jobLauncher.run(job, new JobParameters(map));

}

}

And my Job step configuration class is

public class ProducerBatchJobConfigurer {


private String fileName;

public String getFileName() {
    return fileName;
}
@Value("#{jobParameters['fileName']}")
public void setFileName(String fileName) {
    this.fileName = fileName;
}

@Bean
public ItemReader reader() {
    System.out.println(fileName);
    if (fileName == null)
        return new DummyReader();
    FlatFileItemReader faltFileReader =  new FlatFileItemReader();

    faltFileReader.setResource(new FileSystemResource(new File(fileName)));
    faltFileReader.setResource(new FileSystemResource(new File(fileName)));
    DefaultLineMapper<KafkaMessage> lineMapper = new DefaultLineMapper<KafkaMessage>();
    lineMapper.setLineTokenizer(new DelimitedLineTokenizer());
    lineMapper.setFieldSetMapper(new CSVFieldMapper());
    faltFileReader.setLineMapper(lineMapper);
    return faltFileReader;
}

@Bean
public ItemProcessor processor() {
   return new CustomItemProcessor();

}

@Bean
public ItemWriter writer() {
    return new KafkaWriter();
}



@Bean
public Step step1(StepBuilderFactory stepBuilderFactory,
                  ItemReader reader, ItemWriter writer,
                  ItemProcessor processor) {
    System.out.println("ddddddddddddddd");
    return stepBuilderFactory.get("step1")
            .chunk(10).reader(reader)
            .processor(processor).writer(writer).build();
}
@Bean
public StepScope stepScope() {
    final StepScope stepScope = new StepScope();
    stepScope.setAutoProxy(true);
    return stepScope;
}
@Bean
public JobScope jobScope(){
    return new JobScope();
}
}
Bill Goldberg
  • 1,699
  • 5
  • 26
  • 50
  • ProducerBatchJobConfigurer is not a bean by it self, i would use the @value on the ItemReader Beandefinition reader(@Value ....) – Michael Pralow Mar 04 '16 at 07:10
  • Thanks a lot Michael. Now with your change fileName gets populated. But cannot run the job.Step fails with the following error. ```org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read. at org.springframework.batch.item.file.FlatFileItemReader.readLine(FlatFileItemReader.java:195) ~[spring-batch-infrastructure-3.0.6.RELEASE.jar:3.0.6.RELEASE]``` – Bill Goldberg Mar 04 '16 at 07:53
  • I had to put @Scope("job") also on top of reader else it was giving error ```Property or field 'jobParameters' cannot be found ``` But Unfortunately cannot run the job . Step fails with the following error. ```org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read. at org.springframework.batch.item.file.FlatFileItemReader.readLine(FlatFileItemReader.java:195) ~[spring-batch-infrastructure-3.0.6.RELEASE.jar:3.0.6.RELEASE]``` – Bill Goldberg Mar 04 '16 at 08:06
  • please try it with ItemStreamReader or concrete FlatFileItemReader as Beantype, see http://stackoverflow.com/questions/23847661/spring-batch-org-springframework-batch-item-readernotopenexception-reader-must, if it works you or me can post it as solution – Michael Pralow Mar 04 '16 at 10:22
  • @MichaelPralow : Thanks. It is working. Please go ahead and post it as solution. Please explain a bit more if possible. :) – Bill Goldberg Mar 04 '16 at 10:53
  • @MichaelPralow : If possible please check one of my another issue Asked here [Question](http://stackoverflow.com/questions/35791180/). – Bill Goldberg Mar 04 '16 at 10:55

2 Answers2

3
@Bean
public ItemReader reader() {
 ...
}

should be changed to

@Bean
public ItemStreamReader reader() {
 ...
}

or even more specific

@Bean
public FlatFileItemReader reader() {
 ...
}

Step definition should be changed as well to

@Bean
public Step step1(StepBuilderFactory stepBuilderFactory,
                  ItemStreamReader reader, ItemWriter writer,
                  ItemProcessor processor) {

}

Why is that necessary?

If an itemReader implements the ItemStream Interface (or ItemStreamReader) Spring will treat it as a such.

see https://docs.spring.io/spring-batch/reference/html/readersAndWriters.html#delegatePatternAndRegistering

A reader, writer, or processor that is directly wired into the Step will be registered automatically if it implements ItemStream or a StepListener interface.

that means spring will call the open, update and close methods

similar problem at Spring Batch: org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read

Community
  • 1
  • 1
Michael Pralow
  • 6,560
  • 2
  • 30
  • 46
-1

Use @Value("#{jobParameters[fileName]}") instead of @Value("#{jobParameters['fileName']}")

shazin
  • 21,379
  • 3
  • 54
  • 71