2

I'm building a plugin that is implemented as a Spring MVC application. This plugin is deployed on 3 - 6 tomcat servers via a gui on one of the servers. Each of the instances of the plugin has an @Scheduled method to collect information on the server and store it in a central database.

My issue is that the gui interface for uninstalling the plugin leaves some of the @Scheduled threads running.

For example, I have an environment that has servers 1 - 3. I install and enable the plugin via the gui on server 1. There are now 3 instances of the application running @Scheduled threads on servers 1 - 3. If I go back to server 1 and uninstall the plugin, the thread is reliably killed on server 1 but not servers 2 or 3.

I've implemented the following but the behavior persists:

@Component
public class ContextClosedListener implements ApplicationListener<ContextClosedEvent> {
    @Autowired 
    ThreadPoolTaskExecutor executor;

    @Autowired 
    ThreadPoolTaskScheduler scheduler;

    public void onApplicationEvent(ContextClosedEvent event) {
        scheduler.shutdown();
        executor.shutdown();
    }  
}

Additionally, I've thought of implementing this as a context listener rather than an @Scheduled method but I'd rather stick to Spring for maintenance and extensibility reasons.

How can I reliably kill threads in an environment like this?

Massless
  • 151
  • 1
  • 3

1 Answers1

0

A couple thoughts I have. ThreadPoolTaskExecutor has a method setThreadNamePrefix, which allows you to set the prefix of the thread. You could set the prefix to something unique, then find and kill those threads at runtime. You can also set the thread group using the setThreadGroup method on the same object, then just stop the threads in the threadgroup.

The better, and safer, solution would be to create a break-out method in your scheduled jobs. This is the prefered method to stopping a Thread instead of the old "shot it in the head" method of calling Thread.stop(). You could get reference to those Runnables either by setting a common prefix or by using the thread group as described above.

The next question is: how do you stop the threads easily? For that, it would depend on how your appliation is implemented. Since I deal mainly with Spring MVC apps, my first solution would be to write a Controller to handle admin tasks. If this was JBoss, or some other large app server that had JMX (Tomcat can be configured to provide JMX I believe, but I don't think its configured out of the box that way), I might write a JMX-enabled bean to allow me to stop the threads via the app servers console. Basically, give your self a method to trigger the stopping of the threads.

CodeChimp
  • 8,016
  • 5
  • 41
  • 79