Spring-boot: Cannot create asynchronous JobLauncher

Created on 2 Oct 2014  路  9Comments  路  Source: spring-projects/spring-boot

The Spring Boot implementations does not set any TaskExecutor so it defaults to SyncTaskExecutor. And there is no way (as I know) to override the default jobLauncher bean because of this line in BasicBatchConfigurer which creates a default jobLauncher:

@PostConstruct
    public void initialize() {
        try {
            this.transactionManager = createTransactionManager();
            this.jobRepository = createJobRepository();
            this.jobLauncher = createJobLauncher();
            this.jobExplorer = createJobExplorer();
        }
        catch (Exception ex) {
            throw new IllegalStateException("Unable to initialize Spring Batch", ex);
        }
    }

I also tried to autowire jobLauncher and set the TaskExecutor by myself. But because I can only autowire the interface, I can't call jobLauncher.setTaskExecutor(simpleAsyncTaskExecutor).

duplicate

Most helpful comment

In my case, I'm launching job from REST API, so I have to @Autowired JobLauncher inside my @Controller, I do like following (but I must not fit all case):

@Bean
public JobLauncher asyncJobLauncher() {
    SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
    jobLauncher.setJobRepository(jobRepository);
    jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
    return jobLauncher;
}

Pay attention on bean name, I must not be jobLauncher or it will not load.
Then when using it:

@Autowired
@Qualifier("asyncJobLauncher")
private JobLauncher jobLauncher

It's not clean but a bit easier than overriding whole BatchConfigurer that do not fit Spring Boot philosophy :)

But I'm waiting for a real solution

All 9 comments

How funny, i was having this problem just yesterday as well, with regular Spring. I was able to create my own SimpleJobLauncher by overriding the getJobLauncher() method and returning my own lazily-initialized instance. However my code breaks if I set a TaskExecutor that uses different threads.. probably just my implementation though.

One option is to declare your own bean that implements BatchConfigurer.

To help with that, we could perhaps make createJobExplorer() protected so that you can extend BasicBatchConfigurer and override that one method.

You mean createJobExplorer()? Yes, you could do it that way.

In my case, I'm launching job from REST API, so I have to @Autowired JobLauncher inside my @Controller, I do like following (but I must not fit all case):

@Bean
public JobLauncher asyncJobLauncher() {
    SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
    jobLauncher.setJobRepository(jobRepository);
    jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
    return jobLauncher;
}

Pay attention on bean name, I must not be jobLauncher or it will not load.
Then when using it:

@Autowired
@Qualifier("asyncJobLauncher")
private JobLauncher jobLauncher

It's not clean but a bit easier than overriding whole BatchConfigurer that do not fit Spring Boot philosophy :)

But I'm waiting for a real solution

@kakawait - I think i need to kiss you for this code :+1:

Hi @kakawait,
When using the "public JobLauncher asyncJobLauncher()" my tasks aren't getting run at all,

What I did was:

@Autowired
private JobRepository jobRepository;

@Autowired
private Job job;

@Test
public void testLaunchJob() throws Exception {


    JobExecution execution = asyncJobLauncher().run(job, new JobParameters());

    System.out.println("\n\n\nTomer\n\n\n");

    System.out.println("Exit Status : " + execution.getStatus());
    System.out.println("Exit Status : " + execution.getAllFailureExceptions());
}

@Bean
public JobLauncher asyncJobLauncher() {
    SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
    jobLauncher.setJobRepository(jobRepository);
    jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
    return jobLauncher;
}

Help will be appreciated,

Thanks,
Tomer

@tomerku this tracker is not the right place for asking such question. Please ask them on Stackoverflow.

Will do. Thanks.

Actually, I think this issue can be closed. createJobLauncher() is protected as of #4888 so all you need to do really is create your own BatchConfigurer that provides a custom JobLauncher.

Was this page helpful?
0 / 5 - 0 ratings