Results 1 to 3 of 3

Thread: Dynamically setting FlatFileItemReader.resource

  1. #1
    Join Date
    Jun 2012
    Posts
    5

    Question Dynamically setting FlatFileItemReader.resource

    Hi everyone, I have pretty much solved my external mapping issue however have one additional problem to solve for.

    I would like to be able to modify the resource property of FlatFileItemReader at runtime with a value sourced earlier in the job.

    I have the current job:

    Code:
    <job id="processTrades">
    	<step id="step1" next="step2">
    		<tasklet ref="mappingLoaderTasklet" />
    	</step>
    	<step id="step2">
    		<tasklet>
    			<chunk reader="tradeReader" processor="tradeProcessor" writer="tradeWriter" commit-interval="1" />
    		</tasklet>
    	</step>
    </job>
    mappingLoaderTasklet is used to load a static class with some mapping details from an external configuration file that can be used throughout the job.

    Code:
    package com.windebank.projects.tradeloader;
    
    import org.apache.log4j.Logger;
    import org.springframework.batch.core.StepContribution;
    import org.springframework.batch.core.scope.context.ChunkContext;
    import org.springframework.batch.core.step.tasklet.Tasklet;
    import org.springframework.batch.repeat.RepeatStatus;
    
    public class MappingLoaderTasklet implements Tasklet {
    
    	final Logger logger = Logger.getLogger(MappingLoaderTasklet.class);
    	
    	private String inputFile;
    
    	public String getInputFile() {
    		return inputFile;
    	}
    
    	public void setInputFile(String inputFile) {
    		this.inputFile = inputFile;
    	}
    
    	public RepeatStatus execute(StepContribution contribution,
    			ChunkContext chunkContext) throws Exception {
    
    		TradeMapping.inputFile = inputFile;
    		TradeMapping.read();
    		
    		logger.info("MappingLoaderTasklet: " + inputFile);
    
    		return null;
    	}
    }
    One of these mapping fields is the input file location that I want used by the ItemReader. I would like to be able to effectively do the following:

    Code:
    FlatFileItemReader.resource = TradeMapping.fileName
    I just don't know how this can work when interacting with the beans. I know I can use late binding from the JobParameters as follows:

    Code:
    <beans:bean name="tradeReader"
    	class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
    	<beans:property name="lineMapper" ref="tradeLineMapper" />
    	<beans:property name="resource" value="#{jobParameters['inputFile']}" />
    </beans:bean>
    However this still isn't late enough binding for what I want.

    Anyone got any ideas please?

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,632

    Default

    If you don't expose the inputFile as job parameter it will not be available. You only set it inside your tasklet and not as a job parameter, hence your binding isn't working. You can store the attribute/add it to the execution context and retrieve it from there. If my memory serves me well there is either a sample doing that or it is written out in the Spring Batch Reference Guide.

    Also storing attributes in a class with static members isn't a very good idea IMHO (what happens if you have 2 instances of the job running, what about restartability ?!). But that is just IMHO ofcourse .
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Jun 2012
    Posts
    5

    Default

    Thanks Marten. I am only using the static members for now to solve the problem of not being able to pass objects around, however the execution context appears to solve this. Thank you!

    I have one additional question I'm hoping someone can help with please. If I look at how to implement functionality to save an object to the execution context, it requires me to modify the ItemReader. Eg:

    Code:
    public class SavingItemWriter implements ItemWriter<Object> {
        private StepExecution stepExecution;
    
        public void write(List<? extends Object> items) throws Exception {
            // ...
    
            ExecutionContext stepContext = this.stepExecution.getExecutionContext();
            stepContext.put("someKey", someObject);
        }
    
        @BeforeStep
        public void saveStepExecution(StepExecution stepExecution) {
            this.stepExecution = stepExecution;
        }
    }
    This looks fine except my program is using the built in FlatFileItemReader and so I have nowhere to add the code as required. I am trying to get my head around this and it looks like I might need a delegate, or to extend the FlatFileItemReader. Am I on the right path here please? If so, can anyone provide any tips or references for me as the Spring Batch Reference is a little light on info around these.

    Thanks again.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •