5

Is it possible to implement a background process in a servlet!?

Let me explain. I have a servlet that shows some data and generate some reports. The generation of the report implies that the data is already present, and it is this: someone else upload these data.

In addition to report generation, I should implement a way to send an email on arrival of new data (uploaded).

tshepang
  • 10,772
  • 21
  • 84
  • 127
sangi
  • 479
  • 3
  • 12
  • 23

2 Answers2

19

The functional requirement is unclear, but to answer the actual question: yes, it's possible to run a background process in servletcontainer.

If you want an applicationwide background thread, use ServletContextListener to hook on webapp's startup and shutdown and use ExecutorService to run it.

@WebListener
public class Config implements ServletContextListener {

    private ExecutorService executor;

    public void contextInitialized(ServletContextEvent event) {
        executor = Executors.newSingleThreadExecutor();
        executor.submit(new Task()); // Task should implement Runnable.
    }

    public void contextDestroyed(ServletContextEvent event) {
        executor.shutdown();
    }

}

If you're not on Servlet 3.0 yet and thus can't use @WebListener, register it as follows in web.xml instead:

<listener>
    <listener-class>com.example.Config</listener-class>
</listener>

If you want a sessionwide background thread, use HttpSessionBindingListener to start and stop it.

public class Task extends Thread implements HttpSessionBindingListener {

    public void run() {
        while (true) {
            someHeavyStuff();
            if (isInterrupted()) return;
        }
    }

    public void valueBound(HttpSessionBindingEvent event) {
        start(); // Will instantly be started when doing session.setAttribute("task", new Task());
    }

    public void valueUnbound(HttpSessionBindingEvent event) {
        interrupt(); // Will signal interrupt when session expires.
    }

}

On first creation and start, just do

request.getSession().setAttribute("task", new Task());
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • Thank you for your replay. Sorry. The request asked me is to implement a way to send email (an alert) when some data uploaded (new data loaded in DB). I had thought to implement this mechanism by modifying existing web application, creating background process that polling on new data. The data are loaded by some other application that I don't manage. Servlet container is Tomcat. Thanks for answers – sangi Jun 21 '10 at 13:35
  • Why don't you just write this directly after the piece of code which updates the data in DB? – BalusC Jun 21 '10 at 13:48
  • Because I have not access to application that loads data: it is managed and developed by other people that I can't reach. – sangi Jun 22 '10 at 17:13
  • This thread isn't blocking is it? – Thomas Mar 03 '13 at 18:00
0

Thank you! I was wondering whether this should be better done inside of an request scope like:

public class StartServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {                   
        request.getSession().setAttribute("task", new Task());     
    }
}

This way, the process is stopped when the user leaves the page.

Julian Dehne
  • 83
  • 1
  • 3