我正在通过CommandLineRunner
运行春季批处理作业。我希望我的工作运行的方式是每次运行创建一个新的JobInstance
,如果jobExecution
未能完成,我将使用--restart
参数重新运行该作业,它应该找到之前的执行并恢复jobExecution
,而不是创建新的jobInstance
。
以下是我的JobConfig课程。
@Slf4j
@Configuration
public class JobConfig {
@Autowired
List<Job> jobsToRun; //Jobs annotated as a Components
@Bean
public CommandLineRunner commandLineRunner(JobLauncher jobLauncher,
JobRepository jobRepository, JobOperator jobOperator, JobExplorer jobExplorer) {
return args -> {
JobParameters parameters = new JobParametersBuilder()
.addLong("timestamp", System.currentTimeMillis())
.toJobParameters();
SimpleCommandLinePropertySource cli = new SimpleCommandLinePropertySource(args);
jobsToRun.forEach(job -> {
try {
if (!cli.containsProperty("restart")) {
jobLauncher.run(job, parameters);
} else {
long jobInstanceId = jobOperator.getJobInstances(job.getName(), 0, 1).get(0);
long lastExecutionId = jobOperator.getExecutions(jobInstanceId).get(0);
if (jobExplorer.getJobExecution(lastExecutionId).getStatus() == BatchStatus.FAILED) {
jobOperator.restart(lastExecutionId);
log.info("Restarting the job " + job.getName());
} else {
log.warn("Cannot restart the job. Job not in Failed state.");
}
}
} catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException | JobParametersInvalidException e) {
log.error(
"Error occured while running job " + job.getName() + " Reason: " + e.getMessage());
} catch (NoSuchJobException | NoSuchJobInstanceException | NoSuchJobExecutionException e) {
e.printStackTrace();
}
});
};
}
}
此配置收集我的所有作业bean并通过此CommandLineRunner
bean运行它们。
我在没有--restart
参数的情况下运行作业,一切运行正常。
接下来,当我故意将工作失败并尝试使用--restart
参数运行时,应用程序会抛出org.springframework.batch.core.launch.NoSuchJobException: No job configuration with the name [itemJob] was registered
。
我通过程序调试jobInstanceId
,而jobExecutionId
似乎是正确的ID。一个重要的是应用程序不会将任何内容记录为错误。我只是在INFO级别获得此异常。不知道我在这里错过了什么。
更清楚。如果可能有帮助,我还在这里包含一个作业组件bean。
@Component
@Slf4j
@Profile("master")
@ConditionalOnProperty(name = "item", havingValue = "true")
public class ItemImportJob {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private ItemRemotePartition itemRemotePartition;
@Bean
@Profile("master")
public Job itemJob() throws Exception {
return jobBuilderFactory.get("itemJob").listener(new JobExecutionListener() {
@Override
public void beforeJob(JobExecution jobExecution) {
log.info("Ready to start the job");
}
@Override
public void afterJob(JobExecution jobExecution) {
log.info("Job successfully executed.");
}
}).incrementer(new RunIdIncrementer())
.start(itemRemotePartition.masterStep())
.build();
}
}
NoSuchJobException的完整日志:
2018-02-06 13:29:35.789 INFO 82332 --- [ main] c.a.s.p.b.BulkImportProductApplication : Started BulkImportProductApplication in 19.762 seconds (JVM running for 21.76)
org.springframework.batch.core.launch.NoSuchJobException: No job configuration with the name [itemJob] was registered
at org.springframework.batch.core.configuration.support.MapJobRegistry.getJob(MapJobRegistry.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy117.getJob(Unknown Source)
at org.springframework.batch.core.launch.support.SimpleJobOperator.restart(SimpleJobOperator.java:275)
at org.springframework.batch.core.launch.support.SimpleJobOperator$$FastClassBySpringCGLIB$$44ee6049.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:669)
at org.springframework.batch.core.launch.support.SimpleJobOperator$$EnhancerBySpringCGLIB$$587272bf.restart(<generated>)
at com.art.service.product.bulkimportproduct.config.job.JobConfig.lambda$null$0(JobConfig.java:52)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at com.art.service.product.bulkimportproduct.config.job.JobConfig.lambda$commandLineRunner$1(JobConfig.java:44)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:732)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:716)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:703)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:304)
at com.art.service.product.bulkimportproduct.BulkImportProductApplication.main(BulkImportProductApplication.java:17)
如果我能帮助您解决可能有助于找出问题所在的任何其他细节,请告诉我。提前谢谢。