Reputation: 37
I'm newbie in sprint batch, and I couldn't find an answer for my problem.
I'm trying to implement a JOB using spring boot and spring batch. My JOB needs a parameter, so I'm executing the application like this:
java -jar -Dspring.profiles.active=gus /applications/botbit-batch/botbit-batch-1.0.0.jar --spring.batch.job.names=persistCustomerSuccessMetrics date=2015-12-13
In bold, is the parameter I need.
I executed the application a first time, but in later executions my job allways use the parameter I passed in the first execution.
The logs shows:
Running default command line with:
[spring.batch.job.names=persistCustomerSuccessMetrics, date=2015-12-13]
and a few lines after:
Job: [FlowJob: [name=persistCustomerSuccessMetrics]] launched with the following parameters:
[{date=2015-12-12, -spring.batch.job.names=persistCustomerSuccessMetrics, run.id=2}]
The date 2015-12-12 is the date from first execution, and I'm not able to execute the job again with a different parameter.
My job setup:
@Bean
@JobScope
public CustomerSuccessMetricsReader customerSuccessMetricsReader(@Value("#{jobParameters[date]}") String date) {
return new CustomerSuccessMetricsReader(storeStatisticsUrl, restTemplate, date);
}
@Bean
public CustomerSuccessMetricsProcessor customerSuccessMetricsProcessor() {
return new CustomerSuccessMetricsProcessor();
}
@Bean
public Job persistCustomerSuccessMetrics(Step persistCustomerSuccessMetricsStep1) {
return jobBuilderFactory.get("persistCustomerSuccessMetrics").incrementer(new RunIdIncrementer())
.listener(new CustomerSuccessMetricsCompletionListener()).flow(persistCustomerSuccessMetricsStep1).end().build();
}
@Bean
public Step persistCustomerSuccessMetricsStep1() {
return stepBuilderFactory.
get("persistCustomerSuccessMetricsStep1").
<CustomerSuccessMetricsDTO, CustomerSuccessMetricsDTO> chunk(10).
reader(customerSuccessMetricsReader(null)).
processor(customerSuccessMetricsProcessor()).
//writer(customerSuccessMetricsWriter).
build();
}
I've tried to remove the incrementer(new RunIdIncrementer()) In that case it works fine, but I'm not able to repeat de execution with the same parameters.
So, i need to implement this job with the following rqs:
I'll appreciate any help. Regards
Upvotes: 0
Views: 6726
Reputation: 1
in my case I have to run the job periodically using scheduler so i have to return a new job instance every time it gets from spring context Job job = (Job) context.getBean("methodName");
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Job methodName() {
String jobName = "methodName" + System.currentTimeMillis();
return jobBuilderFactory.get(jobName)
.start(step1()).on("COMPLETED").
to(step2()).end().build();
}
Upvotes: 0
Reputation: 31710
I've tried to remove the incrementer(new RunIdIncrementer()) In that case it works fine, but I'm not able to repeat de execution with the same parameters.
By design, it is not possible to re-run a job instance once it is complete (if you try to do it, a JobInstanceAlreadyCompleteException
will be thrown). You can re-run the same instance if the last execution failed, but once it is complete, you cannot run it again. This is explained in details with an example here: https://docs.spring.io/spring-batch/4.0.x/reference/html/domain.html#jobinstance
The job must take execution parameter, and not the parameter stored in database
The job must support multiple executions with the same parameter.
What you can do is to continue using the RunIdIncrementer
as you do it now but make the date a non-identifying parameter. This way, the run.id
parameter will contribute to the identification of your job instance (and hence you will have a new instance each run) but the date
parameter will not contribute to the identification of the job instance. Non-identifying job parameters should be prefixed with "-" (See javadoc of the DefaultJobParametersConverter).
Hope this helps.
Upvotes: 1
Reputation: 1
The problem is how getNexJobParameters is working. It takes the JobParameters of the last execution of the last(!) instance of the job and put this as input to the JobParameterIncrementer. This way usually the new instance will inherit the parameters of an in some sense arbitrary job instance. This will obviously include non-identifying parameters as well. You can override the old parameter value explicitly on the command line.
Upvotes: 0
Reputation: 21
[Background] I have the same issue in that I have a single parameter for my job that I pass on the command line as follows:
$ java -jar ./target/[java-executable-jar].jar file=[file-path]
I have noticed that on a fresh spring batch meta-database this works fine for the first time, after that if I ran with a different file, Spring Batch uses the file path that was stored in the batch repository meta-database.
I tried all of the above proposed solutions and none works, as it was stated. I used the ".incrementer(new RunIdIncrementer())", it didn't work in making the job execution unique. I also tried passing the file parameter as a non identifying parameter like this:
$ java -jar ./target/[java-executable-jar].jar --file=[file-path]
I also tried adding a timestamp parameter, it didn't help Also it didn't work.
This seems to be an issue in the batch version as according to the documentation I able to make the job execution unique and the job to use the new file (the file is different everytime, not the same one in the first run.
Finally I had to revert to a hack to force solving the issue for me which is as follows:
[Solution] force naming the job differently for every time the app is ran. This way:
@Bean
public Job sampleJob() throws Exception {
String jobName = "sampleJob" + System.currentTimeMillis();
return jobBuilderFactory.get(jobName)
.incrementer(new RunIdIncrementer())
.start(step1()).on("COMPLETED").to(successFileArchiveStep())
.from(step1()).on("*").to(failureFileArchiveStep())
.end()
.build();
}
Upvotes: 2