A little bit of everything

情報系大学院生の備忘録

cron4j を使ってみた - JavaVM上 で動く cron

そもそも cron とは

cron とは、 定期的に or 指定した時刻に、何らかの処理を実行させたい場合に使うUNIX系のOSの仕組みです。いわゆるスケジューラというプログラムです。
サーバ管理を任されるとよく、「サーバのバックアップを取るためのプログラムを毎朝AM4:00に自動で動かす」みたいなことをしたくなります。そのときに cron というコマンドを使うことが多いです。
Windows でも、タスクスケジューラという似たような機能が使えます。使いにくいけど。

cron4j とは

cron を JVM上で実装するためのライブラリが cron4j です。これを使うと、Java で cron っぽいことをできるようになります。
つまり、このライブラリを使うと、「一度実行すると10分に1回 “Hello” と出力する Java のプログラム」などを簡単に書けるようになります。

cron4j を使ってみる

(1) まず、ここから cron4j-X.X.X.zip をダウンロードする cron4j - a pure Java cron-like scheduler

(2) その zipファイルを解凍する。

(3) 解凍して出てきたファイルに入っている cron4j-X.X.X.jar にパスを通す。
これで、Javaソースコードの中から cron4j の機能を呼べるようになります。

コードの書き方は、まず、cron で実行させたいモジュールを Runnable なクラスとして定義します。

class ScheduledTask implements Runnable{
    @Override
    public void run() {
        System.out.println("hello");
    }
}

次に、Scheduler の schedule()メソッドに、crontab でおなじみの “ * * * * * ” と、実行する Runnable なクラスを渡し、start() するだけ!
“ * * * * * ” の部分を変えてあげれば、1時間に1回実行とか、◯月◯日の×時×分に実行とか、色んなスケジュールを定義できます。
詳しくは、マニュアルを。cron4j - Documentation and manual

import it.sauronsoftware.cron4j.Scheduler;

public class Main {
    public static void main(String[] args) {
        Scheduler scheduler = new Scheduler();
        scheduler.schedule("* * * * *", new ScheduledTask());
        scheduler.start();
    }
}

これで、1分毎に “hello” と言うだけのプログラムが完成。

ただし、これだと Javaの 中で Runnable クラスで定義したコードしか実行できない。もっと、色んなコマンドとか実行させたいときは、ちゃんと本家の cron っぽい使い方もできるようになっています。

本家の cron っぽい使い方をする場合

本家の cron は crontab -eで設定ファイルとしてスケジュールを定義しておき、それを cron デーモンが読み込んで実行するという形態。
これと同じように、外部ファイルにスケジュールを定義して、それを定期的に実行する方法があります。つまり、JVM で動く cron デーモンを作っているような感じです。

まずは、実行させたい外部ファイルを定義し、テキトーにcrontab.txt と名付けます。

* * * * * say "hello" 

自分は Mac を使っているので、say コマンドが使えます。これは、引数に渡した文字列を Mac が喋ってくれる(音声が出る)というコマンドです。

コマンド/say - MacWiki


次に、Java コードはこれだけです。

import it.sauronsoftware.cron4j.Scheduler;

public class Main {
    public static void main(String[] args) {     
        Scheduler scheduler = new Scheduler();
        scheduler.scheduleFile(new File("crontab.txt"));
        scheduler.start();
    }
}

これで実行すると、1分に1度、Mac が “Hello” って喋ってくれます。


また、外部ファイルからスケジュールを読んで実行させたいけど、実行させる内容は Java コード内に書きたい!という場合は、public クラスを作り、static 修飾子がついて、引数に String クラスの配列を取るメソッドを定義する必要があります。

public class Test{
    public static void print(String[] s){
        for(int i=0; i<s.length; i++)
            System.out.println(i+"番目の引数: " + s[i]);
        System.out.println();
    }
}

こんな感じ。

そして crontab.txt の中身は、

* * * * * java:Test#print "こんにちは" "Hello" "ni hao"

のように、「java:クラス名#メソッド名 引数1 引数2 …」とします。

これを実行すると、

0番目の引数: こんにちは
1番目の引数: Hello
2番目の引数: ni hao

が、1分毎に出力されるだけの関数が作れました。こんな感じで、外部ファイルから Java 内で定義したメソッドを呼び出して使います。




これで Java で cron と同じことができるようになります。