Whenever I need to perform a long-running function in Enterprise
Java, I use what I call a "null servlet".
A null
servlet is a servlet that has no action processors (doGet, doPost). Instead, it simply has an init() method that spawns a
thread or threads to run the long-running processes in.
Most commonly, this thread (or a dispatcher, if there are multiple threads) will pull requests from a work queue, and the UI part of the webapp will place the requests into the work queue. I may include a request monitoring component as well. Since there are multi-threading concerns here, the work queue is a synchronized data structure.
UI requests may not spawn threads themselves, and it's usually not safe for monitoring components such as session listeners to do so either. But the null servlet is a tried-and-true solution.
One final caveat. Be sure that there's a way to inform the null servlet's threads of server shutdown requests, or they won't let the server terminate.