Membuat job scheduler / cron / daemon dengan Java menggunakan Spring dan Quartz

Jika kita menggunakan *NIX atau Linux, kita akan familiar dengan istilah cron atau daemon. Di Windows jika kita buka Control Panel, juga ada tools yang disebut dengan Scheduled Tasks. Semuanya memiliki kemiripan, yaitu menjalankan sebuah task / job / perintah pada sistem operasi tersebut. Di Windows lebih mudah dalam setting-nya karena sudah ada GUI yang mempermudah untuk membuat schedule. Hanya saja, cron di *NIX / Linux memiliki fleksibilitas yang lebih baik pada pola – schedule pattern-nya, meskipun bagi yang belum biasa akan sedikit susah karena harus mempelajari schedule pattern dari cron dan juga membuat script dari cron itu sendiri.

Dengan Java, tidak terlampau sulit untuk melakukan hal yang sama dengan yang dilakukan oleh sistem operasi tersebut, hanya beda cara saja, yang satu built in dari sistem operasi, sedangkan dengan Java perlu sedikit programming🙂 . Schedule ini bisa kita gunakan untuk keperluan aplikasi kita sendiri, atau untuk eksekusi perintah lain di sistem operasi (dengan menggunakan java.lang.Runtime).

Untuk membuat job scheduler dalam Java, sebenarnya telah ada class java.util.Timer dan java.util.TimerTask yang akan membantu kita membuat cron ala kita sendiri. Tapi pasti akan sulit bagi kita untuk ‘building application from the scratch’ alias mulai semua dari awal, apalagi jika aplikasi berkembang ke arah yang lebih kompleks, misalnya akses ke database atau menggunakan library lain misalnya Hibernate / Ibatis. Terlebih jika harus melakukan hardcode, yang notabene tidak fleksibel.

Bersyukurlah karena telah ada library yang mempermudah melakukan hal tersebut. Team OpenSymphony telah membuat Quartz – full-featured, open source job scheduling system – library untuk job scheduling yang open source di bawah lisensi Apache 2.0 yang bisa digunakan di berbagai aplikasi Java, baik Java EE (a.k.a. J2EE) maupun Java SE (a.k.a. J2SE). Sebagai info tambahan, OpenSymphony ini juga yang menelurkan SiteMesh (web decoration framework) dan WebWork (web-application development framework, yang menjadi cikal bakal Struts 2).


Integrasi dan penggunaan Quartz ini dengan library / framework ini akan lebih mudah lagi jika kita gunakan Spring. Selanjutnya kita akan bahas lebih dalam pengintegrasian Quartz ini ke dalam Spring. Kita asumsikan bahwa anda telah mengenal Spring dan POJO – Plain Old Java Object atau JavaBeans, sebuah class Java sederhana yang menggambarkan sebuah object yang mengenkapsulasi propertinya dengan getter dan setter, lebih sering disebut sebagai bean saja.
Dalam dokumentasi Spring menyebutkan, kita bisa menggunakan Trigger, Job dan JobDetail dari object Quartz, dan menyediakan tiga metode untuk eksekusinya:

  1. JobDetailBean
  2. MethodInvokingJobDetailFactoryBean
  3. SchedulerFactoryBean

Dari tiga metode tersebut, yang paling fleksibel untuk digunakan adalah metode yang terakhir (karena di dalamnya sudah memasukkan dua metode yang lain), yaitu menggunakan SchedulerFactoryBean untuk mengeksekusi method dari bean dengan trigger tertentu, misalnya cron.

Pertama yang perlu kita lakukan adalah membuat POJO / bean yang berisi method untuk mengeksekusi sebuah perintah. Di bawah ini merupakan contoh sebuah bean dengan method sendMail() yang akan dijalankan oleh Quartz. Bean ini memiliki property seperti dataSource yang akan diisi (inject) oleh spring dengan datasource yang telah didefinisikan di context spring.

package contoh;


import javax.sql.DataSource;


public class SimpleBean
{

private DataSource dataSource;

public DataSource getDataSource()
{
return dataSource;
}

public void setDataSource(DataSource dataSource)
{
this.dataSource = dataSource;
}

public void sendMail() throws Exception
{

// do detail job execution here donk...

}

}

Kemudian kita masukkan bean yang telah kita buat tersebut ke dalam Spring Context:


<bean id="cronSimpleBean" class="contoh.SimpleBean">
<!--
Sebuah bean dengan id appDataSource
berupa DataSource, baik jdbc atau dari jndi
yang telah kita masukkan ke dalam Spring Context
di-inject ke dalam property dataSource dari SimpleBean
-->
<property name="dataSource" ref="appDataSource" />
</bean>

Kita bungkus (encapsulate) bean cronSimpleBean tersebut dengan MethodInvokingJobDetailFactoryBean dari Spring yang akan dibuat menjadi object JobDetail di Quartz. Perlu diperhatikan disini adalah property targetObject yang kita tujukan kepada bean cronSimpleBean, dan targetMethod yang kita tujukan pada method yang akan dieksekusi, yaitu sendMail.


<bean id="cronSimpleBeanInvokingJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="cronSimpleBean"/>
<property name="targetMethod">
<value>sendMail</value>
</property>
</bean>

Langkah selanjutnya adalah membuat trigger yang akan mengatur kapan job tersebut dijalankan. Ada dua class yang bisa digunakan untuk mengatur job ini, yaitu CronTriggerBean dan SimpleTriggerBean. Disarankan menggunakan class CronTriggerBean karena lebih fleksibel, dan model eksekusi class SimpleTriggerBean pun sebenarnya juga bisa dibuat dengan CronTriggerBean.


<bean id="cronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="cronSimpleBeanInvokingJobDetail"/>
</property>
<property name="cronExpression">
<!--
Diisi dengan cron yang mirip dengan cron pada *NIX / Linux.
Kita bisa ganti juga dengan property holder di Spring yang
telah kita definisikan, misalnya ${mail.cron}.
Dalam contoh di bawah ini, cron akan dijalankan
setiap hari pada pukul 6 sampai dengan pukul 10, menit 0 dan 30.
-->
<value>0 0,30 6-10 * * ?</value>
</property>
</bean>

Cron yang digunakan di sini mirip dengan cron pada *NIX / Linux. Hanya bagian yang mendefinisikan job saja yang dihilangkan. Untuk mendalami cron lebih jauh bisa dipelajari dari spesifikasinya, unix manual – man crontab, wikipedia atau sumber lain di internet.

Langkah terakhir adalah memasukkan cron tersebut ke dalam SchedulerFactoryBean sebagai bean utama yang mengatur schedule tersebut. Kita bisa memasukkan sebanyak mungkin trigger ke dalam list property triggers.


<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
<!--
Kita bisa masukkan trigger yang lain yang telah kita buat.
<ref bean="simpleTrigger" />
-->
</list>
</property>
</bean>

Mudah bukan??🙂

Sebagai catatan, apabila anda menggunakan Spring sebagai IOC – Inversion of Control, perlu diperhatikan penamaan (id) dari beberapa bean yang telah dibuat. Misalnya untuk DataSource pada bean SimpleBean tersebut di atas kita isi dengan dataSource dengan nama appDataSource. Kita beri id DataSource utama dengan nama appDataSource, karena apabila kita namakan id dataSource, akan terjadi konflik pada SchedulerFactoryBean, karena SchedulerFactoryBean memiliki property dataSource yang akan otomatis diisi oleh IOC apabila bean dengan id tersebut ada dalam context.

Posted in IT, jAVA. 6 Comments »

6 Responses to “Membuat job scheduler / cron / daemon dengan Java menggunakan Spring dan Quartz”

  1. galih Says:

    hwesyah… asumsine…. “sudah mengenal pojo + spring” dhuwure rek.. requirement-e..😦 btw, great article, aku nyaris bikin task scheduler sendiri kalau ndak dikasih tahu kalau spring udah ada fasilitas hebat ini🙂

  2. linda Says:

    sori OOT
    met kenal juga By
    makasih ya dah mampir

  3. nandipinto Says:

    Mas,

    Gimana caranya ya me-restart (stop, start) job schedulernya, programatically?

    Matur nuwun,
    nandi

  4. d'aby Says:

    ambil nama beannya dari spring context, trus start/stop aja.

  5. sandy Says:

    hi,,kalo mau ngetest bahwa trigernya berjalan sesuai cron gimana??kalo pake maven??

    makasih yaa…

    sandy

  6. sandy Says:

    udah bisa deng …. pake
    mvn jetty:run-war
    di folder schedule nya

    makasih yaa…hehe

    Sandy


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: