NoSuchJobException 当 运行 以编程方式在 Spring 批处理中执行作业时
NoSuchJobException when running a job programmatically in Spring Batch
我有一份工作 运行正在启动。我想 运行 在我的应用程序的特定点以编程方式完成这项工作,而不是在我启动我的应用程序时。
当 运行 启动时我没有问题,但是当我尝试以编程方式 运行 它时我得到了 "NoSuchJobException" (No job configuration with the name [importCityFileJob] was registered
)。
网上看了一下,觉得是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();
}
(我试图在我的 运行 批处理方法中将 importCityFileJob
替换为 importFileJob
,但没有成功)
我的 BatchConfiguration 文件包含上面的作业声明、步骤声明、itemReader/itemWriter/itemProcessor,仅此而已。
我使用 @EnableBatchProcessing
注释。
我是 Spring Batch 的新手,我被这个问题困住了。欢迎任何帮助。
谢谢
编辑:我已经解决了我的问题。我在答案中写下了我的解决方案
A JobRegistry
不会自行填充。在您的示例中,您正在创建一个新实例,然后尝试从中获取工作而不首先注册它。通常,JobRegistry
与 AutomaticJobRegistrar
一起配置为一个 bean,它将在启动时将所有作业加载到注册器中。这并不意味着它们将被处决,只是被注册以便稍后可以找到它们。
如果您正在使用 Java 配置,这应该使用 @EnableBatchProcessing
注释自动发生。使用该注释,您只需注入提供的 JobRegistry
并且作业应该已经存在。
您可以在此处的文档中阅读有关 @EnableBatchProcessing
的更多信息:http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.html
您还可以在此处的文档中阅读有关 AutomaticJobRegistrar
的信息:http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/core/configuration/support/AutomaticJobRegistrar.html
这是我必须做的来解决我的问题:
将以下 Bean 添加到 BatchConfiguration 中:
@Bean
public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(JobRegistry jobRegistry) {
JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor = new JobRegistryBeanPostProcessor();
jobRegistryBeanPostProcessor.setJobRegistry(jobRegistry);
return jobRegistryBeanPostProcessor;
}
用 @Autowired
JobRegistry 替换 JobLocator,并使用 @Autowired
JobLauncher 而不是创建一个。我的 运行 方法现在有以下代码:
@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";
}
希望对大家有所帮助。
在 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" />
另一个解决方案:
将方法名"importCityFileJob"重命名为"job":
@Bean
public Job job(JobBuilderFactory jobs, Step step) {
return jobs.get("importFileJob").incrementer(new RunIdIncrementer()).flow(step).end().build();
}
我无法在此页面上找到正确答案。在我的例子中,spring 批处理作业是在不同的配置 class 中配置的,没有使用 @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;
}
}
@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()
我有一份工作 运行正在启动。我想 运行 在我的应用程序的特定点以编程方式完成这项工作,而不是在我启动我的应用程序时。
当 运行 启动时我没有问题,但是当我尝试以编程方式 运行 它时我得到了 "NoSuchJobException" (No job configuration with the name [importCityFileJob] was registered
)。
网上看了一下,觉得是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();
}
(我试图在我的 运行 批处理方法中将 importCityFileJob
替换为 importFileJob
,但没有成功)
我的 BatchConfiguration 文件包含上面的作业声明、步骤声明、itemReader/itemWriter/itemProcessor,仅此而已。
我使用 @EnableBatchProcessing
注释。
我是 Spring Batch 的新手,我被这个问题困住了。欢迎任何帮助。
谢谢
编辑:我已经解决了我的问题。我在答案中写下了我的解决方案
A JobRegistry
不会自行填充。在您的示例中,您正在创建一个新实例,然后尝试从中获取工作而不首先注册它。通常,JobRegistry
与 AutomaticJobRegistrar
一起配置为一个 bean,它将在启动时将所有作业加载到注册器中。这并不意味着它们将被处决,只是被注册以便稍后可以找到它们。
如果您正在使用 Java 配置,这应该使用 @EnableBatchProcessing
注释自动发生。使用该注释,您只需注入提供的 JobRegistry
并且作业应该已经存在。
您可以在此处的文档中阅读有关 @EnableBatchProcessing
的更多信息:http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.html
您还可以在此处的文档中阅读有关 AutomaticJobRegistrar
的信息:http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/core/configuration/support/AutomaticJobRegistrar.html
这是我必须做的来解决我的问题:
将以下 Bean 添加到 BatchConfiguration 中:
@Bean
public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(JobRegistry jobRegistry) {
JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor = new JobRegistryBeanPostProcessor();
jobRegistryBeanPostProcessor.setJobRegistry(jobRegistry);
return jobRegistryBeanPostProcessor;
}
用 @Autowired
JobRegistry 替换 JobLocator,并使用 @Autowired
JobLauncher 而不是创建一个。我的 运行 方法现在有以下代码:
@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";
}
希望对大家有所帮助。
在 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" />
另一个解决方案:
将方法名"importCityFileJob"重命名为"job":
@Bean
public Job job(JobBuilderFactory jobs, Step step) {
return jobs.get("importFileJob").incrementer(new RunIdIncrementer()).flow(step).end().build();
}
我无法在此页面上找到正确答案。在我的例子中,spring 批处理作业是在不同的配置 class 中配置的,没有使用 @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;
}
}
@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()