I have a Spring-Batch job that I launch from a Spring MVC controller. The controller gets an uploaded file from the user and the job is supposed to process the file:
If you don't need to show the processing errors to your client, you can start the spring batch job in a seperate thread.
The jobLauncher.run()
method can be called in a new Thread
like so:
@RequestMapping(value = "/upload")
public ModelAndView uploadInventory(UploadFile uploadFile, BindingResult bindingResult) {
[...]
final SomeObject jobLauncher = [...]
Thread thread = new Thread(){
@Override
public void run(){
jobLauncher.run([...]);
}
};
thread.start();
return mav;
}
The thread.start()
line will spawn a new thread, and then continue to execute the code below it.
Note that, if jobLauncher
is a local variable, it must be declared final
in order for it to be used inside of the anonymous Thread
class.
The official documentation describes your exact problem and a solution in 4.5.2. Running Jobs from within a Web Container:
[...] The controller launches a Job using a
JobLauncher
that has been configured to launch asynchronously, which immediately returns aJobExecution
. The Job will likely still be running, however, this nonblocking behaviour allows the controller to return immediately, which is required when handling an HttpRequest.
Spring Batch http://static.springsource.org/spring-batch/reference/html-single/images/launch-from-request.png
So you were pretty close in trying to use TaskExecutor
, however it needs to be passed to the JobLauncher
instead:
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
<property name="taskExecutor" ref="taskExecutor"/>
</bean>
Disclaimer: I have never used Spring Batch...