Results 1 to 10 of 10

Thread: Help with passing parameters between steps

  1. #1
    Join Date
    Jul 2012
    Posts
    24

    Default Help with passing parameters between steps

    Hello,

    I've already read this thread, but I'm still not able to pass an object from a step to another.

    What I want to do is to get the "parameterName" variable value in Tasklet2 (step2), but I am not able to set the context properly.

    I have a simple Bean, which is as it follows:

    Code:
    import java.io.Serializable;
    
    public class Parameter implements Serializable  {
    
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = -7567239730365058768L;
    	private String parameterName;
    	
    	public void setParameter(String param){
    		parameterName = param;
    	}
    	
    	public String getParameter(){
    		return parameterName;
    	}
    
    }
    I have also two tasklet (which are pretty similar):

    Code:
    public class Tasklet1 implements Tasklet{
    	
    	private StepExecution stepExecution;
     
    	public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception {
    		ApplicationContext appContext = new ClassPathXmlApplicationContext(
    				new String[] { "passingParametersJob.xml" });
    		Parameter parameter = (Parameter) appContext.getBean("parameter");
    		parameter.setParameter("HELLO");	  
    		ExecutionContext stepContext = this.stepExecution.getExecutionContext();
    		stepContext.put("keyValue", parameter);
    		return RepeatStatus.FINISHED; 
    	}	
    	
    	@BeforeStep
    	public void saveStepExecution(StepExecution stepExecution){
    		this.stepExecution = stepExecution;
    	}
    }
    Code:
    public class Tasklet2 implements Tasklet{
    	
    	private Parameter parameter;
     
    	public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception {
    		if(parameter!=null)
    			System.out.print(parameter.getParameter()); 
    		else
    			System.out.println("Missing parameter");
    		return RepeatStatus.FINISHED; 
    	}	
    	
    	@BeforeStep
    	public void retrieveInterstepData(StepExecution stepExecution){
    		JobExecution jobExecution = stepExecution.getJobExecution();
    		ExecutionContext jobContext = jobExecution.getExecutionContext();
    		this.parameter = (Parameter) jobContext.get("keyValue");
    	}
    }
    And this is what I've written in the XML configuration file, within the beans tag:
    Code:
    <bean id="tasklet1" class="com.springbatch.test.Tasklet1"/>
    	
    	<bean id="tasklet2" class="com.springbatch.test.Tasklet2"/>
    	
    	<bean id="parameter" class="com.springbatch.test.Parameter" />
    	
    	<bean id="promotionListener" class="org.springframework.batch.core.listener.ExecutionContextPromotionListener">
    		<property name="keys" value="keyValue" />
    	</bean>
    	 
    	<batch:job id="passingParametersJob" job-repository="jobRepository">
    		<batch:step id="step1" next="step2">
    			<batch:tasklet ref="tasklet1" transaction-manager="jobRepository-transactionManager" />
    			<batch:listeners>
    				<batch:listener ref="promotionListener"/>
    			</batch:listeners>
    		</batch:step>  
    		  	
    		<batch:step id="step2">
    			<batch:tasklet ref="tasklet2" transaction-manager="jobRepository-transactionManager" />
    		</batch:step>
    		
    	</batch:job>
    I've read the documentation, at 11.8. Passing Data to Future Steps paragraph, and I did as above, but the problem is that, executing the job, the following row in Tasklet1 class, falls in a NullpointerException:
    Code:
    ExecutionContext stepContext = this.stepExecution.getExecutionContext();
    As far as I can see, the getExecutionContext() call, returns a NULL value, but I don't understand why.

    Could somebody help me to debug this simple piece of code please?

  2. #2

    Default

    Did tasklet1 complete successfully?

    Jeff

  3. #3
    Join Date
    Jul 2012
    Posts
    24

    Default

    No, because it throws a NullpointerException at this line:
    Code:
    ExecutionContext stepContext = this.stepExecution.getExecutionContext();
    The call to getExecutionContext() fails, because the ExecutionContext returned is null.

  4. #4

    Default

    Why are you implementing your own tasklets?
    Read it again my friend: http://static.springsource.org/sprin...aToFutureSteps
    Last edited by traduz; Aug 1st, 2012 at 08:44 AM.

  5. #5
    Join Date
    Jul 2012
    Posts
    24

    Default

    The answer is: I don't know why. I'm learning spring batch, and I am performing some test.
    The question now is: why should not implement my own tasklet? As far as I've understood, I have to implement my own tasklet for each step of my job, but I guess it is not correct reading your question.

    The class SavingItemWriter, implements a write method. At the moment I am doing some test and I don't understand why I should do so. I think you understand I am a little bit confused, despite that I've read the documentation.

    Thanks for support.

  6. #6

    Default

    No need to implement your own tasklet. Spring batch operates with ItemReader, ItemProcessor and ItemWriter.
    Maybe some books will help you understand it better: Pro Spring Batch is a good one.
    But the documentation is helpfull.

  7. #7
    Join Date
    Jul 2012
    Posts
    24

    Default

    Yes mate, the documentation is always helpful but sometime some doubt can arise, and this is my case, as you can see.
    Thanks for the book suggestion, I'll have a look on it!

    Cheers

  8. #8

    Default

    Sure, any question just post.

  9. #9
    Join Date
    Jul 2012
    Posts
    24

    Default

    Hi!

    here's the reason why I implemented my own simple tasklets.
    I've read something like this, somewhere else, that convinced me to create Tasklets:
    In Spring Batch, a Tasklet represents the unit of work to be done and in our example case, this would be creation of a file in the given path and then populating it with file contents.
    (Resource)
    So I thought that I could create a tasklet to prepare an object with a simple property; pass this object to the following tasklet/step, and another tasklet to get such object to print the value of the property set in the previous step.

    You mentioned ItemReader, ItemProcessor and ItemWriter, and I understand what they are for, but at this point I don't understand why I made a mistake implementing my own tasklets.

    EDIT: maybe I've understood the issue. I have to implement a tasklet for each step. Every tasklet uses the three classes above (Item{Reader,Processor,Writer}), and the object to be passed to the next step, should be saved in one of such three classes. Isn't it?
    Last edited by fbcyborg; Aug 2nd, 2012 at 02:26 AM.

  10. #10

    Default

    My friend never said you shouldn't.
    Yes you need a tasklet for each step. Not sure about the last statement
    and the object to be passed to the next step, should be saved in one of such three classes.
    See if this help you: http://static.springsource.org/sprin...ml#taskletStep
    Last edited by traduz; Aug 2nd, 2012 at 11:03 AM.

Tags for this Thread

Posting Permissions

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