SchedulerFactory 続き

ここでやっとJobの登録。

  long ts = TriggerUtils.getNextGivenSecondDate(null, 15).getTime();

いきなりご登場のTriggerUtilsはTriggerに対するユーティリティクラス。このgetNextGivenSecondDateってのは指定Dateから指定秒数経過後のDateを返してくれる。指定Dateがnullの場合はnew Date()が使用される。このクラスで目に付いたのはmakeXXXTriggerシリーズ。X秒/X分/X時間おき、とかWeeklyとかのTriggerが簡単に作れる。

そしてまず1つ目のJob/Triggerは、

  JobDetail job = new JobDetail("job1", "group1", DumbJob.class);
    SimpleTrigger trigger = new SimpleTrigger("trigg1", "group1", new Date(ts));

てな感じ。まずはJobの情報を保持するJobDetailを作成し、さっき作った15秒後のDateを使ってSimpleTriggerを作成する。この場合、指定Dateになったら1回だけfireする。ちなみに、DumbJobはこんな感じ。

  public void execute(JobExecutionContext context)
            throws JobExecutionException {
        System.err.println("---" + context.getJobDetail().getFullName()
                + " executing.[" + new Date() + "]");
    }

単純に標準エラー出力(何でエラー?)へJobの名前と時刻を出力するだけ。正確にはgetFullNameってのはグループ名+Job名を返す。

でもってSchdulerへの登録。

  Date ft = sched.scheduleJob(job, trigger);

scheduleJobの中身をちらっと追ってみると、まずJobDetailのvaliteが呼ばれて、名前/グループ名/Jobがnullでないことがチェックされ、ひとつでもnullの項目があると例外がすっ飛んでくる。でTriggerに対象Jobの名前/グループ名がnullの場合にはJobDetailの値を設定する。もしTriggerに設定されている対象Jobの名前/グループ名がJobDetailと違う場合には例外がすっ飛ぶ。でもってTriggerもvalidateが呼ばれる。基本的には名前等がnullでないことチェックする。

さらに最初の実行時刻の計算、JobStoreへのJob/Triggerの登録を行い、Schdulerのスレッドにふがふがしてる。まぁこの辺はSchedulerを作るんでもないかぎりそんなに知らなくてもいいようなきがする。最初ってことで少し掘り下げたけれども、こんなことしてたらQuzartz全体を見ることになりかねないので以後はさらりと進めていこう。

2個目のJob/TriggerはSimpleTriggerのコンストラクタフルバージョンを使っただけで内容は1個目と同じ。

  job = new JobDetail("job2", "group1", DumbJob.class);
    trigger = new SimpleTrigger("trigg2", "group1", "job2", "group1", 
           new Date(ts), null, 0, 0);

3個目のJob/Triggerは10秒間隔で10回fireするように設定。

  job = new JobDetail("job3", "group1", DumbJob.class);
    trigger = new SimpleTrigger("trigg3", "group1", "job3", "group1", 
           new Date(ts), null, 10, 10000l);

4個目はJob/TriggerではなくTriggerのみで、こいつは7秒間隔で2回fireする。で今までと違うのはSchdulerへの登録にscheduleJob(trigger)を使っている点。この場合はJobがjob3/group1と既に登録されているJobとなっているためそいつを実行することになる。って特に指定された名前を持つJobが登録されているかどうかはチェックしてないように見える。ひょとしたらJobStoreの方でチェックしてるんかな?ま、この辺はあとで動かして試してみよう。

  trigger = new SimpleTrigger("trigg3", "group2", "job3", "group1",
                  new Date(ts), null, 2, 7000l);
    ft = sched.scheduleJob(trigger);

うーん後はSimpleTrigger.REPEAT_INDEFINITELYを使ったりとかCronTriggerのサンプル。そしてSchedulerがstartした後にもJob/Triggerを設定できるんだよ、ってのがって最後にJobのみ登録してTriggerはコードでfireするなんてのがある。そうそうあとJobに新しいTriggerを再割り当てするってのもある。

ほんで、5分間スリープして好き勝手fireさせたのち、

  sched.shutdown(true);

でSchedulerをシャットダウン。でその実行情報を、

  SchedulerMetaData metaData = sched.getMetaData();
    lg.info("Executed " + metaData.numJobsExecuted() + " jobs.");

てな感じで出力しておしまい。さぁ、実際に動かしてみよう!

2004/08/08 22:21:43 org.quartz.examples.SchedTest schedTest
情報: ------- Shutting Down ---------------------
2004/08/08 22:21:43 org.quartz.core.QuartzScheduler shutdown
情報: Scheduler TestScheduler_$_NON_CLUSTERED shutting down.
2004/08/08 22:21:43 org.quartz.core.QuartzScheduler pause
情報: Scheduler TestScheduler_$_NON_CLUSTERED paused.
2004/08/08 22:21:43 org.quartz.simpl.SimpleThreadPool shutdown
情報: There are still 2 worker threads active. See javadoc runInThread(Runnable)
 for a possible explanation
2004/08/08 22:21:43 org.quartz.core.QuartzScheduler shutdown
情報: Scheduler TestScheduler_$_NON_CLUSTERED shutdown complete.
2004/08/08 22:21:43 org.quartz.examples.SchedTest schedTest
情報: ------- Shutdown Complete -----------------
2004/08/08 22:21:43 org.quartz.examples.SchedTest schedTest
情報: Executed 428 jobs.

でこうなった。前半部分はバサッと削除。いろいろとshutdownの処理しているようだ。ちなみに428回のJobが実行されているのがわかる。

追記:
 さっきのTriggerだけをSchedulerに登録する場合だけど、やっぱりJobStoreで指定されたJobが登録されているかをチェックしている。

  org.quartz.JobPersistenceException: 
    The job (group1.job3d) referenced by the trigger does not exist.
	at org.quartz.simpl.RAMJobStore.storeTrigger(RAMJobStore.java:315)
	at org.quartz.core.QuartzScheduler.scheduleJob(QuartzScheduler.java:612)
	at org.quartz.impl.StdScheduler.scheduleJob(StdScheduler.java:232)
	at org.quartz.examples.SchedTest.schedTest(SchedTest.java:115)
	at org.quartz.examples.SchedTest.main(SchedTest.java:216)