Vicky
Vicky

Reputation: 17405

spring batch: restarting a completed job with same parameters

Is it possible to restart a job in spring batch with same job params, which has completed successfully?

Say I have a job with a step which reads from one file and writes to another.

For test purpose, I need to run the job again and again. However, I do not want the job param (which is today's date which I am reading from a table) to change again and again.

Is such a scenario possible ?

Upvotes: 8

Views: 26718

Answers (5)

vvauban
vvauban

Reputation: 485

I followed the same idea as Serkan Arıkuşu.

My batch can restart with same parameters by adding by the inside each time a unique parameter (timestamp.)

I do this with creating a JobParametersIncrementer.

Here the code sample:

The incrementer:

package com.batch;

import java.util.Date;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersIncrementer;


public class MyIncrementer implements JobParametersIncrementer {

  public JobParameters getNext(JobParameters parameters) {
   long id = new Date().getTime();
   JobParameters jParam = new JobParametersBuilder()
        .addLong("run.id", id).toJobParameters();

   return jParam;
  }
 }

The additional content in the XML of the job:

<bean id="myIncrementer" class="com.batch.MyIncrementer"/>

<job id="myJob" ... restartable="true" incrementer="myIncrementer">
    <step ... >
    <tasklet ...>
        <chunk ... />
        ...
    </tasklet>
   </step>
   <batch:listeners>
    ...
   </batch:listeners>
</job>

Here the screenshot

enter image description here

Upvotes: 0

EliuX
EliuX

Reputation: 12685

I have this function

public void run()
{
    LOG.info("Processing batch...");
    try
    {
        Job job = createNewJob();
        JobParameters jobParameters = new JobParameters();
        Optional<JobInstance> existingInstance = jobExplorer.getJobInstances(job.getName(), 0, 1).stream().findFirst();
        if (existingInstance.isPresent())
        {
            jobParameters = job.getJobParametersIncrementer().getNext(jobParameters);
            LOG.warn("Trying to restart task \"{}\" with the parameters [{}]", job, jobParameters);
        }
        jobLauncher.run(job, jobParameters);
    }
    catch (JobExecutionAlreadyRunningException ex)
    {
        LOG.warn("The task \"{}\" is already running", BillingBatchConfig.QUALIFIER);
    }
    catch (JobRestartException ex)
    {
        LOG.warn("The task \"{}\" cannot be restarted", BillingBatchConfig.QUALIFIER);
    }
    catch (JobInstanceAlreadyCompleteException ex)
    {
        LOG.warn("The task \"{}\" cannot be restarted cause its finished", BillingBatchConfig.QUALIFIER);
    }
    catch (JobParametersInvalidException ex)
    {
        LOG.warn("The task \"{}\" cannot be excecuted cause the parameters are invalid", BillingBatchConfig.QUALIFIER);
    }
    catch (Exception ex)
    {
        LOG.warn("Unexpected error running the task \"{}\"", BillingBatchConfig.QUALIFIER);
    }
}

The key is to check first if there is an existing instance of org.springframework.batch.core.explore.JobExplorer in the database of the wanted job. If its so, the job must be started using the parameters obtained by job.getJobParametersIncrementer().getNext(jobParameters). Thats all.

Upvotes: 0

Jijo
Jijo

Reputation: 610

Spring Batch requires unique job parameters for its execution.so you can add the current time as a job parameter

Map<String, JobParameter> confMap = new HashMap<String, JobParameter>();
confMap.put("time", new JobParameter(System.currentTimeMillis()));
JobParameters jobParameters = new JobParameters(confMap);
jobLauncher.run(springCoreJob, jobParameters);

Upvotes: 6

user1201659
user1201659

Reputation: 66

Long startNextInstance(String jobName) 
      throws NoSuchJobException, JobParametersNotFoundException, JobRestartException, 
             JobExecutionAlreadyRunningException, JobInstanceAlreadyCompleteException;

This method of the JobOperator class along with a JobParameterIncrementer can be used to restart a job, either failed or completed.

http://static.springsource.org/spring-batch/apidocs/org/springframework/batch/core/launch/support/SimpleJobOperator.html#startNextInstance(java.lang.String)

Upvotes: 5

Serkan Arıkuşu
Serkan Arıkuşu

Reputation: 5619

Spring Batch requires unique job parameters for its execution. In your case, if you want to run the same job with the same date parameter, than you should "add" another job parameter to make it unique. You may think of it unique job parameter set.

org.springframework.batch.core.JobParametersIncrementer interface can be used in this scenario, just give it your JobParameter and it will add a run.id that will make it unique.

public class SampleIncrementer implements JobParametersIncrementer {  

    public JobParameters getNext(JobParameters parameters) { 
        if (parameters==null || parameters.isEmpty()) {
            return new JobParametersBuilder().addLong("run.id", 1L).toJobParameters();
        }
        long id = parameters.getLong("run.id",1L) + 1;
        return new JobParametersBuilder().addLong("run.id", id).toJobParameters();
    } }

You may check a simple sample using it

Upvotes: 4

Related Questions