Overview
本節では、ジョブの起動パラメータ(以降、パラメータ)の利用方法について説明する。
本機能は、チャンクモデルとタスクレットモデルとで同じ使い方になる。
パラメータは、以下のような実行環境や実行タイミングに応じてジョブの動作を柔軟に切替える際に使用する。
- 
処理対象のファイルパス 
- 
システムの運用日時 
パラメータを与える方法は、以下のとおりである。
指定したパラメータは、Bean定義やSpring管理下のJavaで参照できる。
How to use
パラメータ変換クラスについて
Spring Batchでは、受け取ったパラメータを以下の流れで処理する。
- 
JobParametersConverterの実装クラスがJobParametersに変換する。
- 
Bean定義やSpring管理下のJavaにて JobParametersからパラメータを参照する。
TERASOLUNA Batch 5.xでは、前述したJobParametersConverterの実装クラスを複数提供する。
以下にそれぞれの特徴を示す。
- 
DefaultJobParametersConverter - 
Spring Batchが提供する。 
- 
パラメータのデータ型は java.io.Serializableを実装した任意のJavaBeansを指定できる。
 
- 
- 
JobParametersConverterImpl - 
TERASOLUNA Batch 5.xが提供する。もともとSpring Batchで提供していたJsrJobParametersConverterを、JSR-352の廃止に伴いTERASOLUNA Batch 5.xへと移植したもの。 
- 
パラメータのデータ型を指定することができない(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が使用される。
しかし、TERASOLUNA Batch 5.xでは以下の理由によりDefaultJobParametersConverterは採用しない。
- 
1つのジョブを同じパラメータによって、異なるタイミングで起動することは一般的である。 
- 
起動時刻のタイムスタンプなどを指定し、異なるジョブとして管理することも可能だが、それだけのためにジョブパラメータを指定するのは煩雑である。 
- 
DefaultJobParametersConverterはパラメータに対しデータ型を指定することができるが、型変換に失敗した場合のハンドリングが煩雑になる。
TERASOLUNA Batch 5.xでは、JobParametersConverterImplを利用することで、ユーザが意識することなく自動的にRUN_IDを付与している。
この仕組みにより、ユーザから見ると同一ジョブをSpring Batchとしては異なるジョブとして扱っている。
ブランクプロジェクトでは、あらかじめLaunchContextConfig.java/launch-context.xmlにてJobParametersConverterImplを使用するように設定している。
そのためTERASOLUNA Batch 5.xを推奨設定で使用する場合はJobParametersConverterの設定を行う必要はない。
@Bean
public JobParametersConverter jobParametersConverter(@Qualifier("adminDataSource") DataSource adminDataSource) {
    return new JobParametersConverterImpl(adminDataSource);
}
@Bean
public JobOperator jobOperator(@Qualifier("jobRepository") JobRepository jobRepository,
                               @Qualifier("jobRegistry") JobRegistry jobRegistry,
                               @Qualifier("jobExplorer") JobExplorer jobExplorer,
                               @Qualifier("jobParametersConverter") JobParametersConverter jobParametersConverter,
                               @Qualifier("jobLauncher") JobLauncher jobLauncher) {
    final SimpleJobOperator simpleJobOperator = new SimpleJobOperator();
    simpleJobOperator.setJobRepository(jobRepository);
    simpleJobOperator.setJobRegistry(jobRegistry);
    simpleJobOperator.setJobExplorer(jobExplorer);
    simpleJobOperator.setJobParametersConverter(jobParametersConverter);
    simpleJobOperator.setJobLauncher(jobLauncher);
    return simpleJobOperator;
}<bean id="jobParametersConverter"
      class="org.terasoluna.batch.converter.JobParametersConverterImpl"
      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" />以降はJobParametersConverterImplを利用する前提で説明する。
コマンドライン引数から与える
まず、もっとも基本的な、コマンドライン引数から与える方法について説明する。
コマンドライン引数としてCommandLineJobRunnerの第3引数以降に<パラメータ名>=<値>形式で列挙する。
パラメータの個数や長さは、Spring BatchやTERASOLUNA Batch 5.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の なお、 | 
| TERASOLUNA Batch 5.xでは、Stepスコープの指定に@StepScopeを使用しない 
 
 しかしTERASOLUNA Batch 5.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) | 
 | 
| TERASOLUNA Batch 5.xでは省略できない必須パラメータ TERASOLUNA Batch 5.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="org.terasoluna.batch.functionaltest.ch04.jobparameter.ComplexJobParametersValidator"/>
    </batch:validator>
</batch:job>| 項番 | 説明 | 
|---|---|
| (1) | 
 | 
| 非同期起動時におけるパラメータの妥当性検証について 非同期起動方式(DBポーリングやWebコンテナ)でも、同様にジョブ起動時に検証することは可能だが、 以下のようなタイミングでジョブを起動する前に検証することが望ましい。 
 非同期起動の場合、結果は別途確認する必要が生じるため、パラメータ設定ミスのような 場合は早期にエラーを応答し、ジョブの要求をリジェクトすることが望ましい。 また、この時の妥当性検証において、 | 
How to extend
パラメータとプロパティの併用
Spring BatchのベースであるSpring Frameworkには、プロパティ管理の機能が備わっており、 環境変数やプロパティファイルに設定した値を扱うことができる。 詳細は、TERASOLUNA Server 5.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が設定されてしまうため注意すること。 誤ったデフォルト値の設定方法例  |