0

I have a configuration class as such:

@Configuration
@EnableAsync
@EnableScheduling
@EnableTransactionManagement
public class SpringAsyncConfiguration implements AsyncConfigurer {

    @Autowired
    private AppConfigProperties appConfigProperties;

    @Autowired
    private AsyncExceptionHandler asyncExceptionHandler;

    @Bean("asyncExecutor")
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(appConfigProperties.getThreadpoolCorePoolSize());
        executor.setMaxPoolSize(appConfigProperties.getThreadpoolMaxPoolSize());
        executor.setQueueCapacity(appConfigProperties.getThreadpoolQueueCapacity());
        executor.setThreadNamePrefix("threadPoolExecutor-");
        executor.initialize();
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return asyncExceptionHandler;
    }
}

And the ExceptionHandler here:

@Component
@Slf4j
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

    @Autowired
    private SynchronizationHelper synchronizationHelper;

    @Override
    public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {

        log.error("*** ASYNC Exception message - " + throwable);

        if("synchronize".equals(method.getName())) {
            synchronizationHelper.(...)
            (...)
        }
    }

}

The problem is that on uncaught exception (in method annotated with @Async), it does not go through the method handleUncaughtException, even though getAsyncUncaughtExceptionHandler() returns the right bean.

Any idea?

UPDATE

I figured out that removing the autowiring in my class AsyncExceptionHandler (which is not what I want), it then enters into the method handleUncaughtException on uncaught exception.

Why is that?

Khalil Bouzekri
  • 210
  • 4
  • 12
  • @M. Deinum Have you just read the **entire** question before marking as duplicate and pointing to a different question? I am not asking about why it is null... – Khalil Bouzekri Oct 31 '18 at 09:36
  • Yes I did. And it is null because it isn't a bean... So to fix make it a bean which is exactly the same as the question marked as duplicate. – M. Deinum Oct 31 '18 at 09:38
  • Which is what I have... I put the example with null at the end to say it goes through at that time, but not when I have a proper bean... – Khalil Bouzekri Oct 31 '18 at 09:43
  • No it isn't... When it is `null` the `AsyncExceptionHandler` isn't a bean, but just an inlined instance creation of it. It isn't seen by spring and hence doesn't receive anything injected. Create an `@Bean` method to construct the instance and call that from the `getAsyncUncaughtExceptionHandler` method. – M. Deinum Oct 31 '18 at 09:43
  • I updated the question by just "removing the last paragraph" which seems to cause a misunderstanding. The code as I mentioned since the beginning gets a proper bean via @Component, or else I am missing something? – Khalil Bouzekri Oct 31 '18 at 09:56
  • @M.Deinum can you "unmark" the question as duplicate? As it is clearly not the same. – Khalil Bouzekri Oct 31 '18 at 10:27

1 Answers1

0

The problem arised from

@Autowired
private SynchronizationHelper synchronizationHelper;

The bean synchronizationHelper was autowired with many beans etc., which somehow (I do not clearly understand how exactly) disabled the behavior of asyncExceptionHandler.

I created a simple @Service bean which only does what I need in my method handleUncaughtException (which is updating the state of my task in DB), which I autowired the same way, and now everything works fine...

I do not time for extra investigations here, if somebody has any idea it would be welcome.

Khalil Bouzekri
  • 210
  • 4
  • 12