Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NoSuchJobException when running a job programmatically in Spring Batch

I have a Job running on startup. I want to run this job programmatically at a particular point of my application, not when I start my app.

When running on startup I have no problem, but I got a "NoSuchJobException" (No job configuration with the name [importCityFileJob] was registered) when I try to run it programmatically.

After looking on the web, I think it's a problem related to JobRegistry, but I don't know how to solve it.

Note : my whole batch configuration is set programmatically, I don't use any XML file to configure my batch and my job. That's a big part of my problem while I lack the examples...

Here is my code to run the 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";
}

My Job declaration :

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

(I tried to replace importCityFileJob by importFileJob in my runBatch method, but it didn't work)

My BatchConfiguration file contains the job declaration above, a step declaration, the itemReader/itemWriter/itemProcessor, and that's all. I use the @EnableBatchProcessing annotation.

I'm new to Spring Batch & I'm stuck on this problem. Any help would be welcome.

Thanks


Edit : I've solved my problem. I wrote my solution in the answers

like image 393
Carrm Avatar asked Mar 04 '15 08:03

Carrm


People also ask

How do you stop a running job in Spring Batch?

With above conditional flag, we're able to trigger the scheduled Spring Batch job with the scheduled task alive. If we don't need to resume the job, then we can actually stop the scheduled task to save resources.

What is job execution context in Spring Batch?

An ExecutionContext is a set of key-value pairs containing information that is scoped to either StepExecution or JobExecution . Spring Batch persists the ExecutionContext , which helps in cases where you want to restart a batch run (e.g., when a fatal error has occurred, etc.).

What is JobExplorer in Spring Batch?

public interface JobExplorer. Entry point for browsing executions of running or historical jobs and steps. Since the data may be re-hydrated from persistent storage, it may not contain volatile fields that would have been present when the execution was active.

What are job parameters in Spring Batch?

JobParameters can be used for identification during the job run. They have reserved names, so to access them we can use Spring Expression Language. For example we can provide the following as job parameters- File path of the source location containing the files to be processed by String Batch.


2 Answers

I could not find the correct answer on this page. In my case the spring batch jobs were configured in a different configuration class not annotated with @EnableBatchProcessing. In that case you need to add the Job to the 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;
    }

}
like image 121
guicey Avatar answered Oct 19 '22 22:10

guicey


Here is what I had to do to fix my problem:

Add the following Bean to the BatchConfiguration :

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

Replace the JobLocator by an @Autowired JobRegistry, and use the @Autowired JobLauncher instead of creating one. My run method now have the following code :

@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";
}

I hope it will help someone.

like image 42
Carrm Avatar answered Oct 19 '22 22:10

Carrm