5

I am writing spring boot app with ThreadPoolTaskExecutor. Here is my Application class:

import info.gandraweb.apns.service.MessageService;
import info.gandraweb.apns.settings.AppSettings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@SpringBootApplication
@EnableScheduling
@EnableAutoConfiguration
@EnableAsync
public class Application implements AsyncConfigurer{


    private static final Logger logger = LoggerFactory.getLogger(Application.class);


    @Autowired
    private AppSettings appSettings;

    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(Application.class, args);
        AppSettings appSettings = applicationContext.getBean(AppSettings.class);
        logger.info(appSettings.toString());

        test(applicationContext);
    }

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setThreadNamePrefix("MyExecutor-");
        taskExecutor.setCorePoolSize(10);
        taskExecutor.setMaxPoolSize(50);
        taskExecutor.setQueueCapacity(1000);
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        taskExecutor.initialize();
        return taskExecutor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }


    private static void test(ApplicationContext applicationContext) {
        MessageService messageService = applicationContext.getBean(MessageService.class);
        messageService.processNewMessages();
    }

}**

inside test method I am calling

messageService.processNewMessages()

which, in turn, if exists some task in DB call Async method on another bean to process it. When there is no tasks for processing app finishes.
If there are any tasks in DB for processing after execution app keep running and never finish .... seems like shutdown() method on ThreadPoolTaskExecutor is never called?

Then I have implemented ApplicationListener interface and logged what is going on inside onApplicationEvent(ContextClosedEvent)

So when there is no task for processing app finish and ContextClosedEvent is triggered. If there are any tasks in DB for processing after execution ContextClosedEvent is not triggered???

When I remove AsyncConfigurer from app then ContextClosedEvent is trigered and app is shutdown. But in such case I have lost posibility to configure ThreadPoolTaskExecutor.

So, how I can configure ThreadPoolTaskExecutor and manage to gracefully shutdown this executor, or to trigger ContextClosedEvent ... whatever is preferred way to gracefully shutdown it?

gandra404
  • 5,727
  • 10
  • 52
  • 76
  • This is answered here http://stackoverflow.com/a/6603443/3166303 – leeor Aug 16 '15 at 22:54
  • I have received error whne tried this way. Error: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contextClosedHandler': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: ... – gandra404 Aug 16 '15 at 23:08
  • @gandra404 did you manage to resolve this error? – Pooja N Babu Aug 30 '19 at 11:36
  • I'm also having this same issue, though my service is a spring batch service. When my job completes the ThreadPoolTaskExecutor is still running and the service doesn't shutdown. Did you ever get the solution in the link above to work? – Joseph Freeman Jan 31 '21 at 03:31

0 Answers0