Quartzで一つのジョブに複数のトリガーを設定する

JavaでCronとかスケジュール実行したい場合に、Quartzってのがある( http://quartz-scheduler.org/ )

基本的な使い方は公式のリファレンスや他所を参照として、1点、はまった点についてメモ。

一つのジョブAに対して、時刻a、時刻b、時刻cの3つの時刻に起動するようなSimpleTriggerを登録したい、といった場合について。
なお、3つの時刻a、b、cはそれぞれ関連がないので、繰り返しやCronTriggerではうまく対応できないとする。

こんな時は、2回目以降のトリガー登録として、

Scheduler#scheduleJob(JobDetail, Trigger);

ではなくて、

Scheduler#scheduleJob(Trigger);

を使うとできる。

以下の例では、ジョブ名"job1"、グループ名"group1"のジョブに対して、"trigger1"、"trigger2"、"trigger3"、"trigger4"の4つのトリガーをスケジューリングしている。

    public void sample() throws Exception {
        Scheduler sche = StdSchedulerFactory.getDefaultScheduler();
        sche.start();

        JobDetail job1 = new JobDetail("job1", "group1", DummyJob.class);

        Date fire1 = new Date();

        Trigger trigger1 = new SimpleTrigger("trigger1", "group1", fire1);
        Trigger trigger2 = new SimpleTrigger("trigger2", "group1", "job1",
                "group1", fire1, null, 0, 0);
        Trigger trigger3 = new SimpleTrigger("trigger3", "group1", "job1",
                "group1", fire1, null, 0, 0);
        Trigger trigger4 = new SimpleTrigger("trigger4", "group1", "job1",
                "group1", fire1, null, 0, 0);

        sche.scheduleJob(job1, trigger1);
        sche.scheduleJob(trigger2);
        sche.scheduleJob(trigger3);
        sche.scheduleJob(trigger4);

        // グループに含まれるトリガー名を表示
        System.out.println(Arrays.toString(sche.getTriggerNames("group1")));

        // ジョブに関連するトリガーを一覧で表示
        Trigger[] triggers = sche.getTriggersOfJob("job1", "group1");
        for (Trigger t : triggers) {
            System.out.println(t.getFullName());
        }

        TimeUnit.SECONDS.sleep(5);

        sche.shutdown();
    }

トリガーのコンストラクタとして、フルコンストラクタを呼んで、ジョブ名やジョブグループ名まで与えているのがポイント。

なお、上の例で"trigger2"を登録する際に、

    sche.scheduleJob(job1, trigger2);

としてしまうと、以下のエラーが出る。

Exception in thread "main" org.quartz.ObjectAlreadyExistsException: Unable to store Job with name: 'job1' and group: 'group1', because one already exists with this identification.

ともかく、やりたいことは実現できそうなことが分かった。

まぁジョブの種類が少なければ、ジョブ自体をそれぞれ別にしてあげて、グループ名でグルーピングしてあげてもいいのだけど、同一グループ内でも上記のように、ひとつのジョブに複数トリガーを割り当てたりすることで、色々できそうなことが分かった。