0

I know this question was asked couple of times but none have provided a correct answer so reposting

I have a Spring4-Jersey webservice that runs inside Tomcat 7.

I am using Spring's ThreadPoolTaskExecutor to process some messages off a queue. I have a bean that uses @Scheduled which submits tasks to the executor every 1000 millis.

However, I have noticed when I shutdown Tomcat, it warns me that it can't shutdown some tasks.

    SEVERE: The web application appears to have started a thread named [taskExecutor-9] but has failed to stop it. This is very likely to create a memory leak.
 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

this what I have in code to initialize taskExecutor

@Bean(destroyMethod="shutdown")
 public Executor taskExecutor() {
     return Executors.newScheduledThreadPool(100);
 }

http://docs.spring.io/spring/docs/3.2.0.RC1_to_3.2.0.RC2/changes/docdiffs_org.springframework.scheduling.annotation.html

mentions that spring would take care of the threads that i created; but unfortunately it doesn't seem to be case...

Could someone provide any pointers ??

harry
  • 310
  • 3
  • 15
  • Possible duplicate of [How can I shutdown Spring task executor/scheduler pools before all other beans in the web app are destroyed?](http://stackoverflow.com/questions/6603051/how-can-i-shutdown-spring-task-executor-scheduler-pools-before-all-other-beans-i) – Praba Feb 27 '16 at 18:32
  • Also check a comment in this answer - quoting " shutdown() and shutdownNow() don't guarantee the pool is fully terminated before returning. However, you could extend the ThreadPoolExecutor class for this purpose. However, you should probably also call executor.awaitTermination as well to make sure the pool is terminated before you exit the onApplicationEvent method" – Praba Feb 27 '16 at 18:34
  • @prabugp yes it is a duplicate of the same question.. But the solution provided there didn't work for me.. And the thread was old.. Wasn't sure if I would get any response that's why I reposted !!! – harry Feb 27 '16 at 19:34
  • There were two options suggested in that answer. You tried both of them? – Praba Feb 27 '16 at 20:16
  • @prabugp: yes, I have tried both the options – harry Feb 28 '16 at 08:54

1 Answers1

1

As its a web-application, you can try something like below;

Your SchedulingConfiguration Class

@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {

    /* Beans and Other Stuff */

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(workers());
    }

    @Bean(name = "executorService")
    ExecutorService workers() {
        return Executors.newScheduledThreadPool(100);
    }

}

ShutDown The ExecutorService in ServletContextListener's contextDestroyed method.

@Configuration
public class CustomServletContextListener implements ServletContextListener {

    @Autowired
    private ExecutorService executorService;

    @Override
    public void contextInitialized(ServletContextEvent context) {
        /* Do stuff If Required */
    }

    @Override
    public void contextDestroyed(ServletContextEvent context) {
        executorService.shutdown();
    }

}

Worked for me and I use Tomcat8.

Rajkishan Swami
  • 3,569
  • 10
  • 48
  • 68