我正在通过 CommandLineRunner 运行一个 Spring 季批处理作业 . 我希望我的工作运行的方式是每次运行创建一个新的 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 .

BATCH_JOB_EXECUTION table

我通过程序调试 jobInstanceIdjobExecutionId 似乎是正确的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)

如果我可以帮助您解决任何可能有助于找出问题的其他细节,请告诉我 . 提前致谢 .