JSR352(Batch Application)を動かして見たので、その記録を残しておくと。
まず、動かしてみたいレベルだったのでサクッと動かすことができそうなBatchletを使っています。
実際にバッチアプリケーションを作成する際は、BatchletにはSQL一発ですむ処理を実装したりするのだと思います。
早速コードなどなどを見ていきます。
ジョブ定義
ジョブ定義は、META-INF/batch-jobs配下にxmlファイルで作成する必要があります。
こんな感じですね。
ファイルの内容は下のようになっています。
そんな難しい構造ではないのでさくっと作れます。jobのid属性には、xmlのファイル名の拡張子をなくしたものを設定します。
今回は、Batchletを動かすので、ステップ定義(step id="step"の部分)にbatchletを定義します。
ref属性には、cdiで管理されているBatchletの名前を設定します。ref属性には、FQCNでBatchletを指定できますが、CDIの管理対象にならないので@Injectが効かなかったりします。(JobContextやStepContextは特別扱いされているっぽくインジェクションされるようです。)
<job id="batchletSample" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> <step id="step"> <batchlet ref="helloWorldBatchlet" /> </step> </job>
Batchletの実装
Batchletの処理はprocessメソッドで行うので、とりあえず実行したジョブ名称をログ(標準出力)に出してみます。
Namedアノテーションをはっているので、ジョブxmlにはこのオブジェクトの名前を設定するだけで良くなります。(前述のジョブxmlのbatchlet部のように)
import javax.batch.api.AbstractBatchlet; import javax.batch.runtime.context.JobContext; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.inject.Named; @Named @Dependent public class HelloWorldBatchlet extends AbstractBatchlet { // ジョブ名称を取得するためにJobContextをインジェクション @Inject JobContext jobContext; @Override public String process() throws Exception { System.out.format("**************************************************%n" + " job name: %s%n **************************************************", jobContext.getJobName()); return "SUCCESS"; } }
バッチ実行用のAPI
jax-rs使って、指定されたバッチジョブを実行する感じにしています。kotlinで書いていますが、Javaで書いてもあまり変わらないと思います。
戻り値は、ジョブの実行を一意に識別できるExecutionIdとしています。このIDは、ジョブのリスタート時に指定したりするので割りと重要な値となっています。
ジョブの実行は、BatchRuntimeからJobOperatorを取得してstartを呼び出すだけです。
このstartメソッドには、ジョブ名称(ジョブxmlの拡張子を除いたもの)を指定します。2番めのパラメータにはバッチ引数を指定するのですが今回は不要なのでnullを渡しています。
@Path(value = "/") open class BatchResource { @GET @Path(value = "/run/{jobName}") open fun start(PathParam("jobName") jobName: String): String { val jobOperator = BatchRuntime.getJobOperator() val executionId = jobOperator.start(jobName, null) return executionId.toString() } }
実行してみよう
端折りますが、バッチ処理と実行用APIをglassfishにデプロイして実行します。glassfishには、JSR352のRIのjBatchがのっています。SE環境でも実行することは可能ですが、面倒臭そうだったのでglassfish上で動かす方を試してみました。
実行は、IntelliJさんのRest Clientからやってみます。
実行してみると、レスポンスとしてExecutionIdが戻ってきます
Batchletで行っているジョブ出力の結果も確認できます。
一応glassfishの管理コンソールからも実行結果を確認できます。
思っていたよりサクッと動いた感があります。
ソースコード全量はこちら→siosio/jbatch-sample · GitHub
おわり。