Sunday 27 November 2011

Using Cron in place of Quartz Enterprise Job Scheduler

If you need to schedule tasks in your Java web application, then there are few options.

On previous projects I have used Spring Framework's scheduling integration, which provides convenience classes for Quartz. This worked well, but a good alternative on Unix-like systems is to use cron.

Here are the steps to get something simple working:

1. Open a terminal and log in to your server

2. Open your crontab for editing:
 
    crontab -e

3. Add a line like this in your crontab:
 
    * * * * * wget -O /tmp/your-domain_scheduler_out http://your-domain.com/scheduler
Make sure you enter the correct domain name. Using localhost will work in some cases, depending on your server's configuration.

4. Now you need to create your scheduler servlet:
// Accessed using path: /scheduler
public class SchedulerServlet extends HttpServlet implements Servlet
{
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException
  {
    // Invoke your scheduler service - something you will need to implement
    SchedulerService.getInstance().doTasks();

    response.setContentType("text/plain");

    PrintWriter out = response.getWriter();

    // Write the current date/time to the response
    out.println((new Date()).toString() + " :: Scheduler invoked");
    out.close();
  }
}
5. Update your web.xml:
  
  <servlet>
    <servlet-name>schedulerServlet</servlet-name>
    <servlet-class>com.your-domain.some.path.SchedulerServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>schedulerServlet</servlet-name>
    <url-pattern>/scheduler</url-pattern>
  </servlet-mapping>
6. Deploy and test:
Compile your serlvet, reload your application and make sure your scheduler servlet works. If the cron job is working correctly you should see the scheduler_out file in your /tmp directory (which will be updated every minute).

7. Improvements for production deployment:
You should consider doing the following before deploying in a production environment:

  • Secure the scheduler servlet by restricting access to the local IP address
  • Instead of invoking wget directly in your crontab, you could invoke a shell script 
  • Handle exceptions and maintain a log file
  • Decide how often the scheduler should run and change your cron entry accordingly.