I have a piece of Java code that I previously used without Spring that looks like this:
// `Callable` instead of `Runnable` because we need to throw exceptions
public MyTask extends Callable<Void> {
@Override
public Void call() throws Exception { ... }
}
public class MyTasksRunner {
private final ExecutorService executorService;
...
public void run() throws Exception {
List<MyTask> tasks = ...;
var futures = executorService.invokeAll(tasks);
for (var future : futures) {
// Rethrow any exceptions happened in the threads.
future.get();
}
}
}
Now I'm merging this code into a larger Spring Boot application that has async enabled. It configures a TaskExecutor, which doesn't have the same interface as ExecutorService. A TaskExecutor can only run Runnables, not Callables.
I can probably have a TaskExecutor bean for async Spring, and another ExecutorService bean for the MyTasksRunner code at the same time. But I wonder what options I have if I want to merge those:
- Can I tell Spring to use an
ExecutorServicefor its async stuff? - Can I convert my
Callablecode to useRunnables instead, while still being able to propagate exceptions from the tasks?
I also thought about just making MyTask a Spring component and annotating it with @Async, but I don't really like that it makes the MyTask* code tied to Spring.