Announcement Announcement Module
Collapse
No announcement yet.
Help with passing parameters between steps Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    Did tasklet1 complete successfully?

    Jeff

    Comment


    • #3
      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.

      Comment


      • #4
        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, 09:44 AM.

        Comment


        • #5
          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.

          Comment


          • #6
            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.

            Comment


            • #7
              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

              Comment


              • #8
                Sure, any question just post.

                Comment


                • #9
                  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, 03:26 AM.

                  Comment


                  • #10
                    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, 12:03 PM.

                    Comment

                    Working...
                    X