Quartz Scheduler: Memakai Ekspresi Cron

Beberapa job mungkin dapat dijadwalkan dengan trigger setiap selang waktu tertentu, misalnya setiap 30 menit, setiap jam, dan sebagainya. Tapi bagaimana dengan job yang harus dikerjakan setiap hari Senin sampai Jumat pada jam 17:30? Solusinya adalah memakai ekspresi yang mirip seperti yang dipakai oleh scheduler UNIX, cron. Untuk itu, Quartz menyediakan CronTrigger. Berikut ini adalah contoh kode program yang memakai CronTrigger:

CronTrigger cronDailyTrigger = new CronTrigger("Daily Trigger",
      Scheduler.DEFAULT_GROUP);
cronDailyTrigger.setCronExpression("0 10 18 ? * MON-FRI *");

Trigger di atas akan dikerjakan setiap jam 18:00 pada hari Senin hingga Jumat. Ekspresi cron pada Quartz lebih lengkap karena terdiri atas 7 bagian, dibandingkan dengan cron di UNIX yang hanya 5 bagian.

Secara berurutan dimulai dari kiri, ekspresi cron di Quartz terdiri atas nilai field yang dipisahkan oleh spasi, yaitu: detik, menit, jam, tanggal, bulan, hari, dan tahun.

Karekter “*” menunjukkan bahwa nilai pada field tersebut boleh bebas.

Karakter “?” hanya dapat dipakai di tanggal dan hari, menunjukkan bahwa kita tidak peduli pada nilai tersebut.

Perhatikan bahwa kita tidak boleh mengisi nilai untuk field tanggal dan field hari secara bersamaan, misalnya pada:
0 10 18 3 * MON *

Ekspresi di atas adalah ekspresi yang tidak valid, karena dapat bermakna ganda. Apakah yang dimaksud adalah tanggal 3 yang jatuh pada hari Senin setiap bulannya? Atau apakah yang dimaksud adalah pada tanggal 3 dan hari Senin setiap minggu? Quartz akan menghasilkan UnsupportedOperationException bila menemukan ekspresi seperti d atas.

Karakter “,” dapat dipakai untuk memisahkan sejumlah nilai untuk sebuah field, misalnya:
0 0 17,18,19 ? * * *
akan aktif setiap setiap jam 17, 18, dan 19.

Karakter “/” menandakan peningkatan, misalnya “0/15” pada field detik menunjukkan aktif setiap 15 detik, dan “0/30” pada menit menunjukkan aktif setiap 30 menit.

Karakter “-” dipakai untuk menunjukkan range/interval, misalnya “0-5” berlaku untuk nilai 0, 1, 2, 3, 4, dan 5.

Karakter “?” menunjukkan nilai terakhir yang berlaku untuk field tersebut. Karakter ini hanya dapat dipakai pada field tanggal dan hari. Misalnya:
0 0 17 L * ? *
menunjukkan bahwa trigger akan aktif pada tanggal terakhir di setiap bulan (bisa saja tanggal 28, 29, 30, atau 31, tergantung pada bulannya), di jam 17:00.

Jika kita menginginkan trigger aktif pada hari Minggu terakhir di setiap bulan, ekspresinya adalah:
0 0 17 ? * 1L *

Karakter “W” hanya dapat dipakai di field tanggal. Nilai seperti 25W akan menunjukkan tanggal yang paling dekat dengan tanggal 25 yang masih merupakan hari kerja.

Karakter “#” hanya dapat dipakai di field hari. Nilai seperti 6#3 menunjukkan hari Sabtu yang ketiga kalinya di bulan tersebut.

Quartz Scheduler: Melewatkan Nilai Ke Job

Jika ada beberapa job yang mengerjakan tugas yang hampir sama, kita dapat menggunakan sebuah class job yang sama, tetapi menerima parameter yang berbeda. Parameter ini nantinya akan di-baca oleh class job melalui getMergedJobDataMap() yang akan mengembalikan JobDataMap yang pada dasarnya adalah sebuah Map.

Sebagai contoh, berikut ini adalah job yang akan membaca parameter “PESAN” dan “SUMBER” dari JobDataMap:

public class TestJob implements Job {

  @Override
  public void execute(JobExecutionContext context)
    throws JobExecutionException {

     JobDataMap jobDataMap = context.getMergedJobDataMap();

     String pesan = jobDataMap.getString("PESAN");
     String sumber = jobDataMap.getString("SUMBER");
     System.out.format("SUMBER [%s] PESAN [%s]\n",
        pesan, sumber);
   }
}

Untuk memberikan nilai pada sebuah job, kita dapat menggunakan getJobDataMap().put() baik pada JobDetail maupun Trigger. Ini adalah contoh kode programnya:

// Membuat scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

// Membuat Job Pertama
JobDetail jobDetail1 = new JobDetail("JOB1",
    Scheduler.DEFAULT_GROUP, TestJob.class);
jobDetail1.getJobDataMap().put("SUMBER", "JOB1");
jobDetail1.getJobDataMap().put("PESAN", "Ini Job Pertama");

// Membuat Job Kedua
JobDetail jobDetail2 = new JobDetail("JOB2",
    Scheduler.DEFAULT_GROUP, TestJob.class);
jobDetail2.getJobDataMap().put("SUMBER", "JOB2");
jobDetail2.getJobDataMap().put("PESAN", "Ini Job Kedua");

// Membuat Trigger Setiap 10 Detik
Trigger trigger10 = TriggerUtils.makeSecondlyTrigger(10);
trigger10.setName("Trigger 10 detik");
trigger10.setStartTime(new Date());
trigger10.getJobDataMap().put("SUMBER", "TRIGGER 10 DETIK");

// Membuat Trigger Setiap 1 Detik
Trigger trigger2 = TriggerUtils.makeSecondlyTrigger(2);
trigger2.setName("Trigger 2 detik");
trigger2.setStartTime(new Date());

// Langkah 4: Menjadwalkan Job
scheduler.scheduleJob(jobDetail1, trigger10);
scheduler.scheduleJob(jobDetail2, trigger2);

// Langkah 5: menjalankan Scheduler
scheduler.start();

Quartz Job Scheduler: Pengenalan

Dalam membangun sebuah sistem enterprise maupun sebuah aplikasi, kita kerap kali membutuhkan scheduler. Sebagai contoh, kita mungkin perlu memeriksa account yang kadaluarsa setiap malam, atau menghapus data yang kadaluarsa secara periodik. Ini merupakan bagian dari aplikasi atau sistem kita!

Cara yang paling sederhana adalah memakai scheduler dari sistem operasi, seperti Windows Scheduler atau cron milik Linux/Unix. Ini berarti kita harus membuat sebuah program terpisah untuk menjalankan tugas yang dijadwalkan. Dari sisi maintenance, ini adalah hal yang buruk, karena kita telah membuat komponen scheduler yang terpisah dari sistem atau aplikasi kita.

Jika sistem atau aplikasi yang dikembangkan memakai teknologi Java, kita dapat menggunakan Quartz scheduler, sebuah framework open-source, sebagai solusi scheduling. Quartz juga sudah mendukung teknologi enterprise seperti clustering. Quartz dapat didownload di lokasi http://terracotta.org/dl/oss-download-destination?name=quartz-1.7.2.tar.gz&bucket=TCreleases&file=quartz-1.7.2.tar.gz.

Untuk memakai Quartz, tambahkan lokasi file quartz-1.7.2.jar ke dalam CLASSPATH. Jangan lupa juga sertakan JAR lain yang dibutuhkan oleh Quartz, seperti commons-logging-1.1.jar, commons-validator-1.3.1.jar, dan seterusnya.

Tugas yang akan dijalankan oleh Quartz scheduler dinamakan job. Setiap job diwakili oleh sebuah class Java yang meng-implementasi-kan interface org.quartz.Job. Kita dapat menuliskan kode program business logic yang akan dikerjakan di method execute(). Berikut ini adalah contoh sebuah job yang mencetak waktu saat ini ke layar:

public class TestJob implements Job {
   @Override
   public void execute(JobExecutionContext context)
      throws JobExecutionException {
         System.out.println("TestJob: [" +
             Calendar.getInstance().getTime() + "]");
   }
}

Untuk menjalankan job tersebut, kita harus membuat scheduler, mendaftarkan job ke dalam scheduler, kemudian menjalankan scheduler, seperti pada contoh kode berikut:

public class Main {
   public Main() {
   try {
      // Langkah 1: Membuat scheduler
     Scheduler scheduler =  StdSchedulerFactory.getDefaultScheduler();

     // Langkah 2: Membuat informasi Job
    JobDetail jobDetail = new JobDetail("Latihan Quartz",
         Scheduler.DEFAULT_GROUP, TestJob.class);

    // Langkah 3: Membuat Trigger Per 10 detik
    Trigger trigger = TriggerUtils.makeSecondlyTrigger(10);
    trigger.setName("Latihan Trigger");
    trigger.setStartTime(new Date());

    // Langkah 4: Menjadwalkan Job
    scheduler.scheduleJob(jobDetail, trigger);

    // Langkah 5: menjalankan Scheduler
    scheduler.start();

   } catch (SchedulerException ex) {
       ex.printStackTrace();
   }
 }

 public static void main(String[] args) {
    new Main();
 }
}