# Executing A Job

## Introduction

In Chapter 2, the overall description of the architecture was discussed, using the following diagram as a guide:

When viewed from left to right, the diagram describes a basic flow for the execution of a batch job:

1. A Scheduler kicks off a job script (usually some form of shell script)

2. The script sets up the classpath appropriately, and starts the Java process. In most cases, using `CommandLineJobRunner` as the entry point

3. The JobRunner finds the `Job` using the `JobLocator`, pulls together the `JobParameters` and launches the `Job`

4. The `JobLauncher` retrieves a `JobExecution` from the `JobRepository`, and executes the `Job`

5. The `Job` executes each `Step` in sequence.

6. The `Step` calls read on the `ItemReader`, handing the resulting item to the `ItemWriter` until null is returned, periodically committing and storing status in the `JobRepository`.

7. When execution is complete, the `Step` returns control back to the `Job`, and if no more steps exist, control is returned back to the original caller, in this case, the scheduler.

This flow is perhaps a bit overly simplified, but describes the complete flow in the most basic terms. From here, each tier will be described in detail, using actual implementations and examples.

## Run Tier

As it's name suggests, this tier is entirely concerned with actually running the job. Regardless of whether the originator is a Scheduler or an HTTP request, a Job must be obtained, parameters must be parsed, and eventually a `JobLauncher` called:

### Running Jobs from the Command Line

For users that want to run their jobs from an enterprise scheduler, the command line is the primary interface. This is because most schedulers (with the exception of Quartz unless using the NativeJob) work directly with operating system processes, primarily kicked off with shell scripts. There are many ways to launch a Java process besides a shell script, such as Perl, Ruby, or even 'build tools' such as ant or maven. However, because most people are familiar with shell scripts, this example will focus on them.

#### The CommandLineJobRunner

Because the script launching the job must kick off a Java Virtual Machine, there needs to be a class with a main method to act as the primary entry point. Spring Batch provides an implementation that serves just this purpose: `CommandLineJobRunner`. It's important to note that this is just one way to bootstrap your application, but there are many ways to launch a Java process, and this class should in no way be viewed as definitive. It performs four tasks:

- Loads the appropriate Application Context

- Parses command line arguments into JobParameters

- Locates the appropriate job based on arguments

- Uses the JobLauncher provided in the application context to launch the job.

All of these tasks are accomplished based completely upon the arguments passed in. The following are required arguments:

##### CommandLineJobRunner arguments

jobPath | The location of the XML file that will be used to create an `ApplicationContext`. This file should contain everything needed to run the complete `Job`
jobName | The name of the job to be run.

These arguments must be passed in with the path first and the name second. All arguments after these are considered to be JobParameters and must be in the format of 'name=value':

    bash$ java CommandLineJobRunner endOfDayJob.xml endOfDay schedule.date(date)=2008/01/01

In most cases you would want to use a manifest to declare your main class in a jar, but for simplicity, the class was used directly. This example is using the same 'EndOfDay' example from Chapter 2. The first argument is 'endOfDayJob.xml', which is the Spring `ApplicationContext` containing the Job. The second argument, 'endOfDay' represents the job name. The final argument, 'schedule.date=01-01-2008' will be converted into `JobParameters`. An example of the XML configuration is below:

      <bean id="endOfDay"
            class="org.springframework.batch.core.job.SimpleJob">
        <property name="steps">
          <bean id="step1" parent="simpleStep" />
          <!-- Step details removed for clarity -->
        </property>
      </bean>

      <!-- Launcher details removed for clarity -->
      <bean id="jobLauncher"
            class="org.springframework.batch.core.launch.support.SimpleJobLauncher" />

This example is overly simplistic, since there are many more requirements to a run a batch job in Spring Batch in general, but it serves to show the two main requirements of the `CommandLineJobRunner`: `Job` and `JobLauncher.`

## Job Tier

The Job Tier is responsible for the overall execution of a batch job. It sequentially executes batch steps, ensuring that all steps are in the correct state and all appropriate policies are enforced:

The job tier is entirely concerned with maintaining the three job stereotypes: `Job`, `JobInstance`, and `JobExecution`. The `JobLauncher` interacts with the `JobRepository` in order to create a `JobExecution`, and the `Job` stores the `JobExecution` using the repository.

### SimpleJobLauncher

The most basic implementation of the `JobLauncher` interface is the SimpleJobLauncher. It's only required dependency is a `JobRepository`, in order to obtain an execution:

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

Once a `JobExecution` is obtained, it is passed to the execute method of `Job`, ultimately returning the `JobExecution` to the caller:

The sequence is fairly straightforward, and works extremely well when launched from a scheduler, but causes issues when trying to launch from an HTTP request. In this scenario, the launching needs to be done asynchronously, so that the `SimpleJobLauncher` returns immediately to it's caller. This is because it is not good practice to keep an HTTP request open for the amount of time needed by long running processes such as batch. An example sequence is below:

The `SimpleJobLauncher` can easily be configured to allow for this scenario by configuring a `TaskExecutor`:

     <bean id="jobLauncher"
            class="org.springframework.batch.execution.launch.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository" />
        <property name="taskExecutor">
          <bean class="org.springframework.core.task.SimpleAsyncTaskExecutor" />
        </property>
      </bean>

Any implementation of the spring `TaskExecutor` interface can be used to control how jobs are asynchronously executed.

#### Stopping a Job

One of the most common reasons for wanting to launching a `job` asynchronously is to be able to gracefully stop it. This can be done through the `JobExecution` returned by the `JobLauncher`:

      JobExecution jobExecution = launcher.run(getJob(), jobParameters);

      //give job adequate time to start
      Thread.sleep(1000);

      assertEquals(BatchStatus.STARTED, jobExecution.getStatus());
      assertTrue(jobExecution.isRunning());

      jobExecution.stop();

      //give job time to stop
      Thread.sleep(1000);

      assertEquals(BatchStatus.STOPPED, jobExecution.getStatus());
      assertFalse(jobExecution.isRunning());

The shutdown is not immediate, since there is no way to force immediate shutdown, especially if the execution is currently in developer code that the framework has no control over, such as a business service. What it does mean, is that as soon as control is returned back to the framework, it will set the status of the current `StepExecution` to `BatchStatus.STOPPED`, save it, then do the same for the `JobExecution` before finishing.

### SimpleJobRepository

The SimpleJobRepository is the only provided implementation of the `JobRepository` interface. It completely manages the various batch domain objects and ensures they are created and persisted correctly. The `SimpleJobRepository` uses three different DAO interfaces for the three major domain types it stores: `JobInstanceDao`, `JobExecutionDao`, and `StepExecutionDao`. The repository delegates to these DAOs to both persist the various domain objects and query for them during initialization. The following configuration shows a SimpleJobRepository configured with JDBC DAOs:

      <bean id="jobRepository" class="org.springframework.batch.core.repository.support.SimpleJobRepository">
        <constructor-arg ref="jobInstanceDao" />
        <constructor-arg ref="jobExecutionDao" />
        <constructor-arg ref="stepExecutionDao" />
      </bean>

      <bean id="jobInstanceDao" class="org.springframework.batch.core.repository.support.dao.JdbcJobInstanceDao" >
        <property name="jdbcTemplate" ref="jdbcTemplate" />
        <property name="jobIncrementer" ref="jobIncrementer" />
      </bean>

      <bean id="jobExecutionDao" class="org.springframework.batch.core.repository.support.dao.JdbcJobExecutionDao" >
        <property name="jdbcTemplate" ref="jdbcTemplate" />
        <property name="jobExecutionIncrementer" ref="jobExecutionIncrementer" />
      </bean>

      <bean id="stepExecutionDao" class="org.springframework.batch.core.repository.support.dao.JdbcStepExecutionDao" >
        <property name="jdbcTemplate" ref="jdbcTemplate" />
        <property name="stepExecutionIncrementer" ref="stepExecutionIncrementer" />
      </bean>

      <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
        <property name="dataSource" ref="dataSource" />
      </bean>

The configuration above isn't quite complete, each DAO implementation is makes a reference to a Spring `DataFieldMaxValueIncrementer`. `JobInstance`, `JobExecution`, and `StepExecution` each have unique IDs, and the incrementers are used to create them.

#### JobRepositoryFactoryBean

Including the incrementers, which must be database specific, the configuration above is verbose. In order to make this more manageable, the framework provides a `FactoryBean` for convenience: `JobRepositoryFactoryBean`.

      <bean id="jobRepository"
            class="org.springframework.batch.execution.repository.JobRepositoryFactoryBean"
        <property name="databaseType" value="hsql" />
        <property name="dataSource" value="dataSource" />
      </bean>

The databaseType property indicates the type of incrementer that must be used. Options include: "db2", "derby", "hsql", "mysql", "oracle", and "postgres".

#### In-Memory Repository

There are scenarios in which you may not want to persist your domain objects to the database. One reason may be speed, storing domain objects at each commit point takes extra time. Another reason may be that you just don't need to persist status for a particular job. Spring batch provides a solution:

      <bean id="jobRepository" class="org.springframework.batch.core.repository.support.SimpleJobRepository">
        <constructor-arg ref="mapJobInstanceDao" />
        <constructor-arg ref="mapJobExecutionDao" />
        <constructor-arg ref="mapJtepExecutionDao" />
      </bean>

      <bean id="mapJobInstanceDao"
            class="org.springframework.batch.execution.repository.dao.MapJobInstanceDao" />

      <bean id="mapJobExecutionDao"
            class="org.springframework.batch.execution.repository.dao.MapJobExecutionDao" />

      <bean id="mapStepExecutionDao"
            class="org.springframework.batch.execution.repository.dao.MapStepExecutionDao" />

The Map* DAO implementations store the batch artifacts in a transactional map. So, the repository and DAOs may still be used normally, and are transactionally sound, but their contents will be lost when the class is destroyed.

### SimpleJob