Scheduling jobs with quartz-jruby

Vagmi Mudumbai

There would be times when you would want to run repetitive tasks once in every few minutes. Like for example, downloading twitter feeds or importing data from one system to another system and so on. Most operating systems have an utility called Cron to do that. Sometimes you may have so many of these small processes that it may not be feasible to fork off a new process every time. It might be easier to have it running as a server. Java has an excellent library called Quartz.

Quartz is a full-featured, open source job scheduling service that can be integrated with, or used along side virtually any Java EE or Java SE application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components that may executed virtually anything you may program them to do. The Quartz Scheduler includes many enterprise-class features, such as JTA transactions and clustering.

The Java Way

To have a simple cron job, you need to write something like this. First you write the job. For example, here we have a cron job that gets fired every 20 seconds.

//SimpleJob.java
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class SimpleJob implements Job {

    private static Logger _log = LoggerFactory.getLogger(SimpleJob.class);
    public SimpleJob() {
    }

    public void execute(JobExecutionContext context)
        throws JobExecutionException {
        // do something complicated
        _log.info("hello job");
    }

}

And then you have to schedule it.

//CronScheduler.java
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;

public class CronScheduler{

    public void run() throws Exception {
        Logger log = LoggerFactory.getLogger(CronScheduler.class);
        
        // First we must get a reference to a scheduler
        SchedulerFactory sf = new StdSchedulerFactory();
        Scheduler sched = sf.getScheduler();

        // jobs can be scheduled before sched.start() has been called

        JobDetail job = new JobDetail("job1", "group1", SimpleJob.class);
        CronTrigger trigger = new CronTrigger("trigger1", "group1", "job1",
                "group1", "0/20 * * * * ?");
        sched.addJob(job, true);
        Date ft = sched.scheduleJob(trigger);
        //start the scheduler
        sched.start();
    }

    public static void main(String[] args) throws Exception {
        CronScheduler example = new CronScheduler();
        example.run();
    }

}

The Ruby Way

Although the above code works, this seems very .... umm... verbose. I have written a wrapper around Quartz that makes it a lot more palatable. Now presenting quartz-jruby. You can install it like below.

$ jruby -S gem install quartz-jruby

Now for some ruby code. This sets up the logger, manages jobs and schedules them with a friendly syntax.

# cron_scheduler.java
require 'java'
require 'rubygems'
gem 'quartz-jruby'
require 'quartz'

# configure log4j the way you want. I am lazy. :-)
org.apache.log4j.BasicConfigurator.configure

class CronScheduler
  
  # this adds all the scheduler stuff to your class
  include Quartz::Scheduler
  schedule(:hello_job, :every=>20.seconds) do 
    # any ruby code
    info "I fire every 20 seconds"
  end

end

# run the scheduler
CronScheduler.instance.run

Feedback

If you would like to check the source, you can visit quartz-jruby on github. Your comments are welcome.

Posted on 2010-12-03T05:21:23Z by Vagmi Mudumbai Comments
blog comments powered by Disqus