Announcement Announcement Module
Collapse
No announcement yet.
More Hello world issues - TaskletStep, StepExecutionListener Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • More Hello world issues - TaskletStep, StepExecutionListener

    Hello,

    I have also tried my luck with the Hello World example, and made it run in its basic configuration. I then tried to expand it, so that I can save details about the jobExecution and the stepExecution in the executionContext.

    I did it by implementing the StepExecutionListener interface in the Tasklet class. That gives me access to the stepExecution (without changing the configuration of the job ??!), but the Id (of the stepExecution) is null.

    Can any of you guide me in the right direction ? My goal is to get access to the stepExecutionId and the jobExecutionId from the Tasklet class.

    helloWorldJob.xml
    Code:
    <beans xmlns=...>  
                                       
      <import resource="helloWorldApplicationContext.xml"/>  
    
      <bean id="printtasklet" class="dk.bec.helloworld.PrintTasklet"/>  
             
      <bean id="hello" parent="printtasklet">
          <property name="message" value="Hello"/>  
      </bean>  
           
      <bean id="space" parent="printtasklet">
          <property name="message" value=" "/>  
      </bean>  
          
      <bean id="world" parent="printtasklet">
          <property name="message" value="World!"/>  
      </bean>  
      
      <bean id="taskletStep" abstract="true" class="org.springframework.batch.core.step.tasklet.TaskletStep">  
          <property name="jobRepository" ref="jobRepository"/>  
    <!--  The below configuration line gives "No property 'listeners' found" -->
    <!--  <property name="listeners" ref="printtasklet"/> -->
      </bean>  
           
      <bean id="simpleJob" class="org.springframework.batch.core.job.SimpleJob">  
          <property name="name" value="simpleJob" />  
          <property name="steps">  
              <list>  
                  <bean parent="taskletStep">  
                      <property name="tasklet" ref="hello"/>  
                  </bean>  
                  <bean parent="taskletStep">  
                      <property name="tasklet" ref="space"/>  
                  </bean>  
                  <bean parent="taskletStep">  
                      <property name="tasklet" ref="world"/>  
                  </bean>  
              </list>  
          </property>  
          <property name="jobRepository" ref="jobRepository"/>  
      </bean>  
    </beans>
    PrintTasklet:
    Code:
    package dk.bec.helloworld;
    
    import org.springframework.batch.core.StepExecution;
    import org.springframework.batch.core.StepExecutionListener;
    import org.springframework.batch.core.step.tasklet.Tasklet;
    import org.springframework.batch.repeat.ExitStatus;
    
    public class PrintTasklet implements Tasklet, StepExecutionListener{   
    	  
    	  private String message;
    	  StepExecution stepExecution;
    	  
    	  public void setMessage(String message) {
    	      this.message = message;
    	  }   
    
    	  public ExitStatus execute() throws Exception {   
    	      System.out.print(message);   
    	      stepExecution.getExecutionContext().putString("Message", message);
    	      stepExecution.getExecutionContext().putDouble("Time", System.currentTimeMillis());
    	      stepExecution.getExecutionContext().putLong("JobExecutionId", stepExecution.getJobExecutionId().longValue());
    
    //		  The .getId() gives java.lang.NullPointerException:	      
    //	      stepExecution.getExecutionContext().putLong("Id", stepExecution.getId().longValue());
    
    	      return ExitStatus.FINISHED;   
    	  }
    
    	public ExitStatus afterStep(StepExecution stepExecution) {
    		// TODO Auto-generated method stub
    		return null;
    	}
    
    	public void beforeStep(StepExecution stepExecution) {
    		this.stepExecution = stepExecution;
    	}
    
    	public ExitStatus onErrorInStep(StepExecution stepExecution, Throwable e) {
    		// TODO Auto-generated method stub
    		return null;
    	}
    
    }

  • #2
    The id is null because StepExecution is not saved yet. Do you really need the value for some reason?

    Comment


    • #3
      Originally posted by robert.kasanicky View Post
      Do you really need the value for some reason?
      Well, maybe I don't need it. I was just pussled, that it was null.

      And then I still can't figure out why the stepExecution works, just because I implemented the StepExecutionListener interface in the Tasklet class. I would have thought that it would take some change to the job configuration xml to make it work.

      Comment


      • #4
        And then I still can't figure out why the stepExecution works, just because I implemented the StepExecutionListener interface in the Tasklet class
        TaskletStep checks whether the Tasklet implements StepExecutionListener, you only need to register nested listeners explicitly.

        Comment


        • #5
          Hi Robert,

          OK. That makes sense. By the way - thank you for all your good work with this framework.

          Best regards
          Preben

          Comment


          • #6
            How do i save into StepExecutioncontext

            I need to save a list of keys into executioncontext so i can retrieve them during a next step.

            Is there a way to do that while running the current taskletstep?

            Comment


            • #7
              Just implement StepExecutionListener so that you can get access to the ExecutionContext.

              Comment


              • #8
                Hi @all,

                I am not that far to execute the first step. I recently used Hivemind as IOC (Unfortunately - but it was company policy in those days) and want to move to Spring now, so there might be some lacks concerning Spring as well.

                I did everything as explained in the example, but somehow the PlatformTransactionManager is null, which results in the following stacktrace.
                Can anyone tell me if - any how - I have to define the TransactionManager myself in this example.v

                Code:
                2008-11-07 11:51:39,012  INFO org.springframework.context.support.ClassPathXmlApplicationContext:412 - Refreshing org.springframework.context.support.
                ClassPathXmlApplicationContext@cade31: display name [org.springframework.context.support.ClassPathXmlApplicationContext@cade31]; startup date [Fri Nov
                 07 11:51:39 CET 2008]; root of context hierarchy
                2008-11-07 11:51:39,079  INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader:323 - Loading XML bean definitions from class path resourc
                e [simpleJob.xml]
                2008-11-07 11:51:39,290  INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader:323 - Loading XML bean definitions from class path resourc
                e [applicationContext.xml]
                2008-11-07 11:51:39,348  INFO org.springframework.context.support.ClassPathXmlApplicationContext:427 - Bean factory for application context [org.sprin
                gframework.context.support.ClassPathXmlApplicationContext@cade31]: org.springframework.beans.factory.support.DefaultListableBeanFactory@14ed577
                2008-11-07 11:51:39,368  INFO org.springframework.beans.factory.support.DefaultListableBeanFactory:414 - Pre-instantiating singletons in org.springfra
                mework.beans.factory.support.DefaultListableBeanFactory@14ed577: defining beans [jobLauncher,jobRepository,hello,space,world,taskletStep,simpleJob]; r
                oot of factory hierarchy
                2008-11-07 11:51:39,454  INFO org.springframework.batch.core.launch.support.SimpleJobLauncher:161 - No TaskExecutor has been set, defaulting to synchr
                onous executor.
                2008-11-07 11:51:39,537  INFO org.springframework.batch.core.launch.support.SimpleJobLauncher:114 - Job: [SimpleJob: [name=simpleJob]] launched with t
                he following parameters: [{}]
                2008-11-07 11:51:39,575 ERROR org.springframework.batch.core.step.AbstractStep:220 - Encountered an error executing the step: class java.lang.NullPoin
                terException: null
                java.lang.NullPointerException
                        at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInStepContext(TaskletStep.java:247)
                        at org.springframework.batch.core.scope.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:67)
                        at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:352)
                        at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:212)
                        at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143)
                        at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:230)
                        at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:198)
                        at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:330)
                        at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:78)
                        at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:228)
                        at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:115)
                        at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:49)
                        at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:110)
                        at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:204)
                        at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:251)
                        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                        at java.lang.reflect.Method.invoke(Method.java:597)
                        at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:271)
                        at java.lang.Thread.run(Thread.java:619)
                2008-11-07 11:51:39,599  INFO org.springframework.batch.core.launch.support.SimpleJobLauncher:116 - Job: [SimpleJob: [name=simpleJob]] completed with
                the following parameters: [{}] and the following status: [FAILED]
                2008-11-07 11:51:39,601  INFO org.springframework.context.support.ClassPathXmlApplicationContext:816 - Closing org.springframework.context.support.Cla
                ssPathXmlApplicationContext@cade31: display name [org.springframework.context.support.ClassPathXmlApplicationContext@cade31]; startup date [Fri Nov 07
                 11:51:39 CET 2008]; root of context hierarchy
                2008-11-07 11:51:39,603  INFO org.springframework.beans.factory.support.DefaultListableBeanFactory:399 - Destroying singletons in org.springframework.
                beans.factory.support.DefaultListableBeanFactory@14ed577: defining beans [jobLauncher,jobRepository,hello,space,world,taskletStep,simpleJob]; root of
                factory hierarchy
                Thanks for your help.

                Thomas

                Comment


                • #9
                  You need a transaction manager (just follow the examples). It looks like you probably aren't using the *StepFactoryBeans that the framework provides to make configuring steps easier. I would recommend you do that (as in the samples) so that you get an early warning about this kind of problem.

                  Comment


                  • #10
                    Mmh.. as far as I can see no StepFactoryBeans are used in the example, but instead TaskletStep. At least not in Step1.
                    As far as I can read from the documentation, the PlatformTransactionManager has only be defined in the StepHandler but not when using Tasklets.
                    Is this true or is it only not mentioned especially in the documentation?

                    Thomas

                    Comment


                    • #11
                      I do not know, if Im on the wrong page or if things have changed that much in the last time. (I am working with this example page http jroller.com/0xcafebabe/entry/spring_batch_hello_world_1). Everything seems to be a bit different now.
                      Now I defined the ResourcelessTransactionManager as a TX-Manager an it works, although I could not find anything on the example page.

                      Anyways: what caught my attention is, that it is possible to define the same name for a tasklet twice. But this can cause problems when the "shouldStart"-method is called in the AbstractJob, because the name of the step is used to get the last execution from the JobRepository. In my case that led to a NPE, because the second step became the last execution of the first step, due to equal names. Is this meant to be this way or is there any chance to do something like a validation on startup to avoid those mistakes?

                      Thanks
                      Thomas
                      Last edited by hamtho; Nov 14th, 2008, 08:52 AM.

                      Comment


                      • #12
                        Hello World Example - Can't Build App

                        Good day,

                        I am having a problem trying to run my first Spring application (I am very new to Spring!). Please help...I will be submitting my files now...

                        Please help as I have to get this running as soon as possible.

                        My main aim is to show creation of a simple Spring Batch Script, then from there develop a bigger application which will run a lot of sub batches from a "Main batch".

                        Please help.

                        Comment


                        • #13
                          Files for Hello World Application

                          applicationContext.xml......
                          ================================================== =========
                          <beans xmlns="http://www.springframework.org/schema/beans"
                          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                          xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

                          <bean id="jobLauncher" class="org.springframework.batch.core.launch.suppo rt.SimpleJobLauncher">
                          <property name="jobRepository" ref="jobRepository"/>
                          </bean>

                          <bean id="jobRepository" class="org.springframework.batch.core.repository.s upport.SimpleJobRepository">
                          <constructor-arg>
                          <bean class="org.springframework.batch.core.repository.d ao.MapJobInstanceDao"/>
                          </constructor-arg>
                          <constructor-arg>
                          <bean class="org.springframework.batch.core.repository.d ao.MapJobExecutionDao" />
                          </constructor-arg>
                          <constructor-arg>
                          <bean class="org.springframework.batch.core.repository.d ao.MapStepExecutionDao"/>
                          </constructor-arg>
                          </bean>

                          </beans>

                          ================================================== =========

                          simpleJob.xml....
                          ================================================== =
                          <beans xmlns="http://www.springframework.org/schema/beans"
                          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                          xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

                          <import resource="applicationContext.xml"/>

                          <bean id="hello" class="helloworld.PrintTasklet">
                          <property name="message" value="Hello"/>
                          </bean>

                          <bean id="space" class="helloworld.PrintTasklet">
                          <property name="message" value=" "/>
                          </bean>

                          <bean id="world" class="helloworld.PrintTasklet">
                          <property name="message" value="World!"/>
                          </bean>

                          <bean id="taskletStep" abstract="true"
                          class="org.springframework.batch.core.step.tasklet .TaskletStep">
                          <property name="jobRepository" ref="jobRepository"/>
                          </bean>

                          <bean id="simpleJob" class="org.springframework.batch.core.job.SimpleJo b">
                          <property name="name" value="simpleJob" />
                          <property name="steps">
                          <list>
                          <bean parent="taskletStep">
                          <property name="tasklet" ref="hello"/>
                          </bean>
                          <bean parent="taskletStep">
                          <property name="tasklet" ref="space"/>
                          </bean>
                          <bean parent="taskletStep">;
                          <property name="tasklet" ref="world"/>
                          </bean>
                          </list>
                          </property>
                          <property name="jobRepository" ref="jobRepository"/>
                          </bean>
                          </beans>
                          ================================================== =
                          printTasklet.java....
                          ================================================== =
                          package java.helloworld;

                          import org.springframework.batch.core.step.tasklet.Taskle t;
                          import org.springframework.batch.repeat.ExitStatus;

                          public class PrintTasklet implements Tasklet{

                          private String message;

                          public ExitStatus execute() throws Exception {
                          System.out.println(message);
                          return ExitStatus.FINISHED;
                          }

                          /**
                          * @param message the message to set
                          */
                          private void setMessage(String message) {
                          this.message = message;
                          }

                          /**
                          * @return the message
                          */
                          private String getMessage() {
                          return message;
                          }

                          }
                          =============================================

                          I have been trying to run this command on Command Line:
                          mvn exec:java -Dexec.mainClass=org.springframework.batch.core.lau nch.support.CommandLineJobRunner -Dexec.args="simpleJob.xml simpleJob"

                          but I get the following error:
                          [INFO] The plugin 'org.apache.maven.plugins:maven-exec-plugin' does not exist or
                          no valid version could be found

                          Comment


                          • #14
                            You have the plugin id wrong. Try org.codehaus.mojo:exec-maven-plugin. Or crib from the simple-cli template in the Spring Batch release and source code.

                            Comment


                            • #15
                              &quot;exec-maven-plugin-1.1.jar&quot; Plugin Included

                              I have just downloaded the exec-maven-plugin-1.1.jar and included it in my application's jars. But i still get that error. Is there anywhere else where I have to include the plugin within the xml's perhaps? I am running it from the Command Line.

                              Comment

                              Working...
                              X