Reputation: 17405
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
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
.
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>
Upvotes: 0
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
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
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.
Upvotes: 5
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