Asakusa Framework Advent Calendar 2013の5日目です。
AsakusaFWでは、Asakusa DSLという独自言語を用いてバッチアプリケーションを記述します。
DSLは「ドメイン特化言語」と言われるもので、限定的な用途に特化した言語のことです。
例えばSQLはRDBの操作に特化した言語であり、Asakusa DSLはバッチアプリケーションの記述に特化した言語、という具合です。
Asakusa DSLには、記述する内容に応じてBatch DSL・Flow DSL・Operator DSLの3種類があります。
(データモデルを記述するDMDLという言語もありますが、これは「Asakusa DSL」には含めないようです)
- Operator DSLでは「演算子」の内容を記述します。
- 演算子と名付けられていますが、実態は普通のJavaのメソッドそのものです。最小粒度の処理はここに記述します。
- バッチの実行時にはこのメソッドが実際に呼ばれます。
- Flow DSLでは、アプリケーションの処理を記述します。
- Operator DSLで記述した演算子(メソッド)を、どの順番で呼び出すのかを記述するイメージです。
- Batch DSLでは、バッチを記述します。
- ひとつのアプリケーション(Windowsで例えればexeファイル)がひとつのバッチとなります。
- バッチの中には実行する「ジョブフロー」を指定します。
- ここで言う「ジョブフロー」はFlow DSLで記述した物の事であり、JP1やA-AUTO等のジョブ管理ツールで言うジョブではありません。むしろ、ジョブ管理ツールにはBatch DSLで作成したバッチを登録します。(バッチはYAESSというシェルを使って実行します)
Batch DSL・Flow DSLもJavaで記述します(「Javaをホスト言語とするDSL」と言われる所以です)が、書いたメソッドがバッチの実行時に呼ばれるわけではありません。
なので、Batch DSLやFlow DSLの中で、通常のJavaの感覚で初期処理とか終了処理を書いても、実行時には呼ばれません。
で、ここからが今日の本題です。
と言いつつ普通のAsakusaFWユーザーは全く知る必要が無い事柄なのですが^^;
AsakusaFWは、Batch DSL・Flow DSLで書かれた内容をコンパイルして実行用のクラスを生成します。
この「コンパイル」ですが、実はBatch DSL・Flow DSLで書かれたクラスを実行しているのです!
例えば記述したBatchクラスをnewしてstart()メソッドを呼び出すと、中でdescribe()メソッド(Batch DSLで記述した本体)が呼ばれるのです。そしてgetWorks()を呼び出すと、記述されていたジョブフローの一覧が取得できたりします。
何が言いたいのかと言うと、一般的に「コンパイル」と言うとソースファイルを解析して云々というイメージですが、AsakusaFWのコンパイルはBatchクラスやFlowクラスを実行する(のであり、ソースファイルを解釈しているのではない)という事です。
(まぁ、汎用言語をホストとする外部DSLは全般的にこういうものかもしれませんが、「Javaで」っていうのが意外と盲点だったもので、驚いたのです)
なので、たぶん、describeメソッド内にSystem.out.println()を入れるとコンパイル時に表示されるし、無限ループを仕込むとコンパイルが終わらなくなると思います(爆)
「Javaをホスト言語とするDSL」である以上、自由にJavaの文が書けてしまうので、仕方ないですね^^;
ただ、AsakusaFWが想定している動作ではないはずなので、こういうことはしない方が良いでしょう。
(なら書くなって声もありそうだけど、書きたかったんじゃー!w)