在Spring Batch中以编程方式运行作业时出现NoSuchJobException

时间:2015-03-04 08:49:15

标签: configuration spring-batch jobs

我在启动时运行了一个Job。我希望以编程方式在我的应用程序的特定位置运行此作业,而不是在我启动应用程序时。

在启动时运行时我没有问题,但我得到了一个" NoSuchJobException" (No job configuration with the name [importCityFileJob] was registered)当我尝试以编程方式运行它时。

在网上看后,我认为这是与JobRegistry有关的问题,但我不知道如何解决。

注意:我的整个批处理配置是以编程方式设置的,我不使用任何XML文件来配置我的批处理和我的工作。当我缺少示例时,这是我问题的一个重要部分......

这是我运行Job的代码:

public String runBatch() {
    try {
        JobLauncher launcher = new SimpleJobLauncher();
        JobLocator locator = new MapJobRegistry();
        Job job = locator.getJob("importCityFileJob");
        JobParameters jobParameters = new JobParameters(); // ... ?
        launcher.run(job, jobParameters);
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("Something went wrong");
    }
    return "Job is running";
}

我的工作声明:

@Bean
public Job importCityFileJob(JobBuilderFactory jobs, Step step) {
    return jobs.get("importFileJob").incrementer(new RunIdIncrementer()).flow(step).end().build();
}

(我尝试在我的runBatch方法中将importCityFileJob替换为importFileJob,但它没有工作)

我的BatchConfiguration文件包含上面的作业声明,步骤声明,itemReader / itemWriter / itemProcessor,以及所有这些。 我使用@EnableBatchProcessing注释。

我是Spring Batch& amp;的新手。我坚持这个问题。欢迎任何帮助。

由于


编辑:我已经解决了我的问题。我在答案中写了我的解决方案

6 个答案:

答案 0 :(得分:20)

以下是我必须采取的措施来解决我的问题:

将以下Bean添加到BatchConfiguration:

@Bean
public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(JobRegistry jobRegistry) {
    JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor = new JobRegistryBeanPostProcessor();
    jobRegistryBeanPostProcessor.setJobRegistry(jobRegistry);
    return jobRegistryBeanPostProcessor;
}

@Autowired JobRegistry替换JobLocator,并使用@Autowired JobLauncher而不是创建一个。我的run方法现在有以下代码:

@Autowired
private JobRegistry jobRegistry;

@Autowired
private JobLauncher launcher;

public String runBatch() {
    try {
        Job job = jobRegistry.getJob("importCityFileJob");
        JobParameters jobParameters = new JobParameters();
        launcher.run(job, jobParameters);
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("Something went wrong");
    }
    return "OK";
}

我希望它会帮助别人。

答案 1 :(得分:4)

JobRegistry不会填充自己。在您的示例中,您正在创建一个新实例,然后尝试从中获取作业而不首先注册它。通常,JobRegistry被配置为bean以及AutomaticJobRegistrar,它将在启动时将所有作业加载到注册器中。这并不意味着它们将被执行,只是注册,以便以后可以找到它们。

如果您正在使用Java配置,则应使用@EnableBatchProcessing注释自动执行此操作。使用该注释,您只需注入提供的JobRegistry,并且作业应该已存在。

您可以在此处的文档中详细了解@EnableBatchProcessinghttp://docs.spring.io/spring-batch/apidocs/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.html

您还可以在此处的文档中了解AutomaticJobRegistrarhttp://docs.spring.io/spring-batch/apidocs/org/springframework/batch/core/configuration/support/AutomaticJobRegistrar.html

答案 2 :(得分:0)

在applicationContext.xml中添加以下bean解决了我的问题

<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
    <property name="jobRegistry" ref="jobRegistry" />
</bean>

我在applicationContext.xml

中也有这个条目
<bean id="jobRegistry"
    class="org.springframework.batch.core.configuration.support.MapJobRegistry" />

答案 3 :(得分:0)

另一种解决方案:

将方法名称“importCityFileJob”重命名为“job”

@Bean
public Job job(JobBuilderFactory jobs, Step step) {
    return jobs.get("importFileJob").incrementer(new RunIdIncrementer()).flow(step).end().build();
}

答案 4 :(得分:0)

我在此页面上找不到正确的答案。在我的情况下,spring批处理作业是在另一个未用@EnableBatchProcessing注释的配置类中配置的。在这种情况下,您需要将Job添加到JobRegistry:

import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.DuplicateJobException;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.support.ReferenceJobFactory;
import org.springframework.batch.core.job.flow.Flow;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBatchJobConfigurations {

    @Bean
    public Job myCountBatchJob(final JobBuilderFactory jobFactory, final JobRegistry jobRegistry, final Flow myJobFlow)
        throws DuplicateJobException {
      final Job countJob = jobFactory.get("myCountBatchJob")
            .start(myJobFlow)
            .end().build();
      ReferenceJobFactory referenceJobFactory = new ReferenceJobFactory(countJob);
      jobRegistry.register(referenceJobFactory);
      return countJob;
    }

}

答案 5 :(得分:0)

@EnableBatchProcessing
@Configuration
public class SpringBatchCommon {

  @Bean
  public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(JobRegistry jobRegistry) {
    JobRegistryBeanPostProcessor postProcessor = new JobRegistryBeanPostProcessor();
    postProcessor.setJobRegistry(jobRegistry);
    return postProcessor;
  }
}

在JobRegistryBeanPostProcessor中设置JobRegistry,之后您可以自动连接JobLauncher和JobLocator

     Job job = jobLocator.getJob("importFileJob");
     JobParametersBuilder jobBuilder = new JobParametersBuilder();
     //set any parameters if required
     jobLauncher.run(job, jobBuilder.toJobParameters()