Overview
本節では、ジョブの起動パラメータ(以降、パラメータ)の利用方法について説明する。
本機能は、チャンクモデルとタスクレットモデルとで同じ使い方になる。
パラメータは、以下のような実行環境や実行タイミングに応じてジョブの動作を柔軟に切替える際に使用する。
-
処理対象のファイルパス
-
システムの運用日時
パラメータを与える方法は、以下のとおりである。
指定したパラメータは、Bean定義やSpring管理下のJavaで参照できる。
How to use
パラメータ変換クラスについて
Spring Batchでは、受け取ったパラメータを以下の流れで処理する。
-
JobParametersConverter
の実装クラスがJobParameters
に変換する。 -
Bean定義やSpring管理下のJavaにて
JobParameters
からパラメータを参照する。
前述したJobParametersConverter
の実装クラスは複数提供されている。
以下にそれぞれの特徴を示す。
-
DefaultJobParametersConverter
-
パラメータのデータ型を指定することができる(String、Long、Date、Doubleの4種類)。
-
-
JsrJobParametersConverter
-
パラメータのデータ型を指定することができない(Stringのみ)。
-
パラメータにジョブ実行を識別するID(RUN_ID)を
jsr_batch_run_id
という名称で自動的に付与する。-
RUN_IDは、ジョブが実行される都度増加する。増加は、データベースのSEQUENCE(名称は
JOB_SEQ
となる)を利用するため、重複することがない。 -
Spring Batchでは、同じパラメータで起動したジョブは同一ジョブとして認識され、同一ジョブは1度しか実行できない、という仕様がある。 これに対し、
jsr_batch_run_id
という名称のパラメータを一意な値で付加することにより、別のジョブと認識する仕組みとなっている。 詳細は、Spring Batchのアーキテクチャを参照。
-
-
Spring BatchではBean定義で使用するJobParametersConverter
の実装クラスを指定しない場合、DefaultJobParametersConverter
が使用される。
しかし、Macchinetta Batch 2.xでは以下の理由によりDefaultJobParametersConverter
は採用しない。
-
1つのジョブを同じパラメータによって、異なるタイミングで起動することは一般的である。
-
起動時刻のタイムスタンプなどを指定し、異なるジョブとして管理することも可能だが、それだけのためにジョブパラメータを指定するのは煩雑である。
-
DefaultJobParametersConverter
はパラメータに対しデータ型を指定することができるが、型変換に失敗した場合のハンドリングが煩雑になる。
Macchinetta Batch 2.xでは、JsrJobParametersConverter
を利用することで、ユーザが意識することなく自動的にRUN_IDを付与している。
この仕組みにより、ユーザから見ると同一ジョブをSpring Batchとしては異なるジョブとして扱っている。
ブランクプロジェクトでは、あらかじめlaunch-context.xml
にてJsrJobParametersConverter
を使用するように設定している。
そのためMacchinetta Batch 2.xを推奨設定で使用する場合はJobParametersConverter
の設定を行う必要はない。
<bean id="jobParametersConverter"
class="org.springframework.batch.core.jsr.JsrJobParametersConverter"
c:dataSource-ref="adminDataSource" />
<bean id="jobOperator"
class="org.springframework.batch.core.launch.support.SimpleJobOperator"
p:jobRepository-ref="jobRepository"
p:jobRegistry-ref="jobRegistry"
p:jobExplorer-ref="jobExplorer"
p:jobParametersConverter-ref="jobParametersConverter"
p:jobLauncher-ref="jobLauncher" />
以降はJsrJobParametersConverter
を利用する前提で説明する。
コマンドライン引数から与える
まず、もっとも基本的な、コマンドライン引数から与える方法について説明する。
コマンドライン引数としてCommandLineJobRunner
の第3引数以降に<パラメータ名>=<値>
形式で列挙する。
パラメータの個数や長さは、Spring BatchやMacchinetta Batch 2.xにおいては制限がない。
しかし、OSにはコマンド引数の長さに制限がある。
そのため、あまりに大量の引数が必要な場合は、ファイルから標準入力へリダイレクトするや
パラメータとプロパティの併用などの方法を活用すること。
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
JobDefined.xml JOBID param1=abc outputFileName=/tmp/result.csv
以下のように、Bean定義またはJavaで参照することができる。
-
Bean定義で参照する
-
#{jobParameters['xxx']}
で参照可能
-
-
Javaで参照する
-
@Value("#{jobParameters['xxx']}")
で参照可能
-
JobParametersを参照するBeanのスコープはStepスコープでなければならない
late bindingとはその名のとおり、遅延して値を設定することである。
Spring Frameworkの なお、 |
Macchinetta Batch 2.xでは、Stepスコープの指定に@StepScopeを使用しない
しかしMacchinetta Batch 2.xでは、以下二つの前提によってStepスコープの指定には
|
<!-- (1) -->
<bean id="reader"
class="org.springframework.batch.item.file.FlatFileItemReader" scope="step"
p:resource="file:#{jobParameters['inputFile']}"> <!-- (2) -->
<property name="lineMapper">
<!-- omitted settings -->
</property>
</bean>
項番 | 説明 |
---|---|
(1) |
|
(2) |
参照するパラメータを指定する。 |
@Component
@Scope("step") // (1)
public class ParamRefInJavaTasklet implements Tasklet {
/**
* Holds a String type value
*/
@Value("#{jobParameters['str']}") // (2)
private String str;
// omitted execute()
}
項番 | 説明 |
---|---|
(1) |
クラスに |
(2) |
|
ファイルから標準入力へリダイレクトする
ファイルから標準入力へリダイレクトする方法について説明する。
パラメータは下記のようにファイルに定義する。
param1=abc
outputFile=/tmp/result.csv
コマンドライン引数としてパラメータを定義したファイルをリダイレクトする。
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
JobDefined.xml JOBID < params.txt
パラメータの参照方法はコマンドライン引数から与える方法と同様である。
パラメータのデフォルト値を設定する
パラメータを任意とした場合、以下の形式でデフォルト値を設定することができる。
-
#{jobParameters['パラメータ名'] ?: デフォルト値}
ただし、パラメータを使用して値を設定している項目であるということは、デフォルト値もパラメータと同様に環境や実行タイミングによって異なる可能性がある。
まずは、デフォルト値をソースコード上にハードコードをする方法を説明する。 しかし、後述のパラメータとプロパティの併用を活用する方が適切なケースが多いため、合わせて参照。
該当するパラメータが設定されなかった場合にデフォルト値に設定した値が参照される。
<!-- (1) -->
<bean id="reader"
class="org.springframework.batch.item.file.FlatFileItemReader" scope="step"
p:resource="file:#{jobParameters[inputFile] ?: /input/sample.csv}"> <!-- (2) -->
<property name="lineMapper">
<!-- omitted settings -->
</property>
</bean>
項番 | 説明 |
---|---|
(1) |
|
(2) |
参照するパラメータを指定する。 |
@Component
@Scope("step") // (1)
public class ParamRefInJavaTasklet implements Tasklet {
/**
* Holds a String type value
*/
@Value("#{jobParameters['str'] ?: 'xyz'}") // (2)
private String str;
// omitted execute()
}
項番 | 説明 |
---|---|
(1) |
クラスに |
(2) |
|
パラメータの妥当性検証
オペレーションミスや意図しない挙動を防ぐために、ジョブの起動時にパラメータの妥当性検証が必要となる場合もある。
パラメータの妥当性検証はSpring Batchが提供するJobParametersValidator
を活用することで実現可能である。
パラメータはItemReader/ItemProcessor/ItemWriterといった様々な場所で参照するため、 ジョブの起動直後に妥当性検証が行われる。
パラメータの妥当性を検証する方法は2つあり、検証の複雑度によって異なる。
簡易な妥当性検証
Spring BatchはJobParametersValidator
のデフォルト実装として、DefaultJobParametersValidator
を提供している。
このバリデータでは設定により以下を検証することができる。
-
必須パラメータが設定されていること
-
必須または任意パラメータ以外のパラメータが指定されていないこと
以下に定義例を示す。
<!-- (1) -->
<bean id="jobParametersValidator"
class="org.springframework.batch.core.job.DefaultJobParametersValidator">
<property name="requiredKeys"> <!-- (2) -->
<list>
<value>jsr_batch_run_id</value> <!-- (3) -->
<value>inputFileName</value>
<value>outputFileName</value>
</list>
</property>
<property name="optionalKeys"> <!-- (4) -->
<list>
<value>param1</value>
<value>param2</value>
</list>
</property>
</bean>
<batch:job id="jobUseDefaultJobParametersValidator" job-repository="jobRepository">
<batch:step id="jobUseDefaultJobParametersValidator.step01">
<batch:tasklet ref="sampleTasklet" transaction-manager="jobTransactionManager"/>
</batch:step>
<batch:validator ref="jobParametersValidator"/> <!-- (5) -->
</batch:job>
項番 | 説明 |
---|---|
(1) |
|
(2) |
必須パラメータは |
(3) |
必須パラメータに |
(4) |
任意パラメータは |
(5) |
|
Macchinetta Batch 2.xでは省略できない必須パラメータ
Macchinetta Batch 2.xではパラメータ変換に
そのため、 パラメータの定義例
|
DefaultJobParametersValidator
にて検証可能な条件の理解を深めるため、検証結果がOKとなる場合とNGとなる場合の例を示す。
<bean id="jobParametersValidator"
class="org.springframework.batch.core.job.DefaultJobParametersValidator"
p:requiredKeys="outputFileName"
p:optionalKeys="param1"/>
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
JobDefined.xml JOBID param1=aaa
必須パラメータoutputFile
が設定されていないためNGとなる。
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
JobDefined.xml JOBID outputFileName=/tmp/result.csv param2=aaa
必須パラメータ、任意パラメータのどちらにも指定されていないパラメータparam2
が設定されたためNGとなる。
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
JobDefined.xml JOBID param1=aaa outputFileName=/tmp/result.csv
必須および任意として指定されたパラメータが設定されているためOKとなる。
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
JobDefined.xml JOBID fileoutputFilename=/tmp/result.csv
必須パラメータが設定されているためOKとなる、任意パラメータは設定されていなくてもよい。
複雑な妥当性検証
JobParametersValidator
インタフェースの実装を自作することで、
要件に応じたパラメータの検証を実現することができる。
JobParametersValidator
クラスは以下の要領で実装する。
-
JobParametersValidator
クラスを実装し、validateメソッドをオーバーライドする -
validateメソッドは以下の要領で実装する
-
JobParameters
から各パラメータを取得し検証する-
検証の結果がOKである場合には、何もする必要はない
-
検証の結果がNGである場合には、
JobParametersInvalidException
をスローする
-
-
JobParametersValidator
クラスの実装例を示す。
ここでは、str
で指定された文字列の長さが、num
で指定された数値以下であることを検証している。
public class ComplexJobParametersValidator implements JobParametersValidator { // (1)
@Override
public void validate(JobParameters parameters) throws JobParametersInvalidException {
Map<String, JobParameter> params = parameters.getParameters(); // (2)
String str = params.get("str").getValue().toString(); // (3)
int num = Integer.parseInt(params.get("num").getValue().toString()); // (4)
if(str.length() > num){
throw new JobParametersInvalidException(
"The str must be less than or equal to num. [str:"
+ str + "][num:" + num + "]"); // (5)
}
}
}
項番 | 説明 |
---|---|
(1) |
|
(2) |
パラメータは |
(3) |
keyを指定してパラメータを取得する。 |
(4) |
パラメータをint型へ変換する。String型以外を扱う場合は適宜変換を行うこと。 |
(5) |
パラメータ |
<batch:job id="jobUseComplexJobParametersValidator" job-repository="jobRepository">
<batch:step id="jobUseComplexJobParametersValidator.step01">
<batch:tasklet ref="sampleTasklet" transaction-manager="jobTransactionManager"/>
</batch:step>
<batch:validator> <!-- (1) -->
<bean class="jp.co.ntt.fw.macchinetta.batch.functionaltest.ch04.jobparameter.ComplexJobParametersValidator"/>
</batch:validator>
</batch:job>
項番 | 説明 |
---|---|
(1) |
|
非同期起動時におけるパラメータの妥当性検証について
非同期起動方式(DBポーリングやWebコンテナ)でも、同様にジョブ起動時に検証することは可能だが、 以下のようなタイミングでジョブを起動する前に検証することが望ましい。
非同期起動の場合、結果は別途確認する必要が生じるため、パラメータ設定ミスのような 場合は早期にエラーを応答し、ジョブの要求をリジェクトすることが望ましい。 また、この時の妥当性検証において、 |
How to extend
パラメータとプロパティの併用
Spring BatchのベースであるSpring Frameworkには、プロパティ管理の機能が備わっており、 環境変数やプロパティファイルに設定した値を扱うことができる。 詳細は、Macchinetta Server 1.x 開発ガイドラインの プロパティ管理 を参照。
プロパティとパラメータを組み合わせることで、大部分のジョブに共通的な設定をプロパティファイルに行ったうえで、一部をパラメータで上書きするといったことが可能になる。
パラメータとプロパティが解決されるタイミングについて
前述のとおり、パラメータとプロパティは、機能を提供するコンポーネントが異なる。
また、それぞれの値が解決されるタイミングが異なる。
よって、Spring Batchによるパラメータの値が優先される結果になる。 |
以降、プロパティとパラメータを組み合わせて設定する方法について説明する。
環境変数による設定に加えて、コマンドライン引数を使用してパラメータを設定する方法を説明する。
Bean定義においても同様に参照可能である。
$ # Set environment variables
$ export env1=aaa
$ export env2=bbb
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
JobDefined.xml JOBID param3=ccc outputFile=/tmp/result.csv
@Value("${env1}") // (1)
private String param1;
@Value("${env2}") // (1)
private String param2;
private String param3;
@Value("#{jobParameters['param3']") // (2)
public void setParam3(String param3) {
this.param3 = param3;
}
項番 | 説明 |
---|---|
(1) |
|
(2) |
|
$ # Set environment variables
$ export env1=aaa
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
JobDefined.xml JOBID param1=bbb outputFile=/tmp/result.csv
@Value("#{jobParameters['param1'] ?: '${env1}'}") // (1)
public void setParam1(String param1) {
this.param1 = param1;
}
項番 | 説明 |
---|---|
(1) |
環境変数をデフォルト値として |
誤ったデフォルト値の設定方法
以下の要領で定義した場合、コマンドライン引数からparam1を設定しない場合に、 env1の値が設定されてほしいにも関わらず、param1にnullが設定されてしまうため注意すること。 誤ったデフォルト値の設定方法例
|