当前位置: 首页 > 知识库问答 >
问题:

在Spring批处理中以编程方式运行作业时,NoSuchJobException

狄信然
2023-03-14

我有一份刚起步的工作。我希望在应用程序的特定点以编程方式运行此作业,而不是在启动应用程序时。

当在启动时运行时,我没有问题,但是当我尝试以编程方式运行它时,我得到了一个“NoSuchJobException”(没有注册名为[importCityFileJob]的作业配置)。

在网上查看之后,我认为这是一个与JobRegistry相关的问题,但我不知道如何解决它。

注意:我的整个批处理配置都是以编程方式设置的,我不使用任何XML文件来配置我的批处理和作业。这是我的一个很大的问题,因为我缺乏例子...

以下是我运行作业的代码:

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注释。

我是新来的

谢啦

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


共有3个答案

周志文
2023-03-14

我在这页上找不到正确答案。在我的例子中,spring批处理作业是在不同的配置类中配置的,没有用@EnableBatchProcessing注释。在这种情况下,需要将作业添加到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;
    }

}
施轶
2023-03-14

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

如果您使用Java配置,这应该使用@EnableBatch处理注释自动发生。有了这个注释,您只需注入提供的Job注册表,作业就应该已经在那里了。

有关@EnableBatchProcessing的更多信息,请参阅以下文档:http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.html

您还可以在此处的文档中阅读关于AutomaticObjRegistrator:http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/core/configuration/support/AutomaticJobRegistrar.html

越高峻
2023-03-14

以下是我必须做的来解决我的问题:

将以下Bean添加到BatchConfiguration:

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

@Autowired作业注册表替换作业定位器,并使用@Autowired作业启动器,而不是创建一个。我的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";
}

我希望它能帮助某人。

 类似资料:
  • 我正在使用spring批处理读取CSV文件并使用controller触发器将其写入DB。在启动应用程序时,在我从浏览器url中点击之前,我会在启动时看到来自阅读器的打印语句。虽然它不为我的处理器或写入器打印它,它们是在单独的类中,我已经自动连线。是因为读者是豆子吗?

  • 我正在做简单的Spring批量工作。当我启动作业时,它在无限循环中运行。它不会停止。根据我的时间表,它应该每10秒运行一次。但当工作开始时,它不会停止。它只是分别从读卡器、处理器和写入器打印系统输出。我正在为读者、处理者和作者创造工作机会。我正在按注释进行所有配置。不是通过xml。 下面是批处理配置 PersonReader。JAVA 人Writer.java 个人处理器。JAVA

  • 问题内容: 运行main方法时,将执行作业。这样我无法弄清楚如何控制作业的执行。例如,您如何安排作业,访问作业执行或设置作业参数的方式。 我试图注册自己的JobLauncher 但是当我尝试在主要方法中使用它时: 当加载上下文时,该作业再次执行,而当我尝试手动运行它时,我得到了。有没有办法防止自动作业执行? 问题答案: 通过设置可以防止作业执行 在application.properties中。或

  • Spring批处理作业与flatfileitemreader(从csv读取)、processor(更新adwords api提要详细信息,对于csv文件中的每个记录(大约有40条记录),这一步大约需要40秒)和正在更新DB中记录的定制writer一起使用。 web.xml

  • 我按照这个示例使用Boot进行Spring批处理。 运行main方法时,作业将执行。这样我就不知道如何控制作业的执行了。例如如何排定作业、访问作业执行或设置作业参数。 我尝试注册自己的JobLauncher 但当我尝试在主法中使用时: 当加载上下文时,再次执行作业,并且尝试手动运行作业时得到。有没有办法防止自动执行作业?