Umumnya aplikasi Java menggunakan Quartz untuk mengatasi penjadwalan tugas pada aplikasi, seperti :
- Tugas yang berjalan setiap 1 jam sekali
- Tugas yang berjalan setiap pukul 07.00 setiap hari
- Tugas yang berjalan setiap pukul 22.00 pada akhir bulan
Adapun umumnya aplikasi Java akan membaca Cron Expression tersebut hanya pada saat pertama kali dijalankan.
Lalu bagaimana bila ingin melakukan penjadwalan proses yang bergantung kepada proses sebelumnya ? Misal proses B dijalankan 5 menit setelah proses A selesai.
Source Code
Untuk masalah tersebut dapat dipecahkan dengan melakukan penjadwalan menggunakan Quartz, berikut potongan kodenya.
//--------POTONGAN KODE-----------
Long startTime = currentTime + (5 * 60); //5 menit
String triggerKeyName = "TaskTriggerKey";
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(TriggerKey.triggerKey(triggerKeyName, "TaskTriggerGroup"))
.withSchedule(SimpleScheduleBuilder
.simpleSchedule()).startAt(new Date(startTime))
.build();
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("DATA_A", "ABCDEFG");
jobDataMap.put("TRIGGER_KEY", trigger.getKey().getName());
JobDetail job = JobBuilder.newJob(NextExecutedJob.class)
.withIdentity("nextExecutedJob", "TaskTriggerGroup")
.setJobData(jobDataMap)
.build();
try {
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Will executed at " + date);
} catch (SchedulerException e) {
e.printStackTrace();
}
//--------POTONGAN KODE-----------
Untuk dapat menjadwalkan secara dinamis, diperlukan obyek Trigger yang berguna untuk menentukan kapan tugas tersebut akan dijalankan.
Obyek jobDataMap berguna untuk menyimpan data-data supaya dapat dibaca pada class NextExecutedJob yang akan dijalankan nanti.
Obyek jobDetail merupakan representasi dari tugas yang akan dijalankan nanti, dan didaftarkan kepada obyek scheduler.
//--------POTONGAN KODE-----------
public class NextExecutedJob extends QuartzJobBean {
public NextExecutedJob() {}
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
String triggerKeyName = null;
JobDataMap jobDataMap = context.getMergedJobDataMap();
String dataA = (String) jobDataMap.get("DATA_A");
triggerKeyName = (String) jobDataMap.get("TRIGGER_KEY");
//do something here
if(null != triggerKeyName) {
TriggerKey triggerKey = new TriggerKey(triggerKeyName, "TaskTriggerGroup");
try {
scheduler.unscheduleJob(triggerKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
}
//--------POTONGAN KODE-----------
Sedangkan pada class NextExecutedJob sebaiknya dilakukan penghapusan job yang tadi didaftarkan dari scheduler. Dengan tujuan menjamin bahwa job tersebut tidak dijalankan lagi oleh scheduler.
Ok, sekian tentang penggunaan Quartz Scheduler secara programatic. Semoga membantu. :)