Overview
本節では、ジョブの起動パラメータ(以降、パラメータ)の利用方法について説明する。
本機能は、チャンクモデルとタスクレットモデルとで同じ使い方になる。
パラメータは、以下のような実行環境や実行タイミングに応じてジョブの動作を柔軟に切替える際に使用する。
-
処理対象のファイルパス
-
システムの運用日時
パラメータを与える方法は、以下のとおりである。
指定したパラメータは、Bean定義やSpring管理下のJavaで参照できる。
How to use
パラメータ変換クラスについて
Spring Batchでは、受け取ったパラメータを以下の流れで処理する。
-
JobParametersConverter
の実装クラスがJobParameters
に変換する。 -
Bean定義やSpring管理下のJavaにて
JobParameters
からパラメータを参照する。
Macchinetta Batch 2.xでは、前述したJobParametersConverter
の実装クラスを複数提供する。
以下にそれぞれの特徴を示す。
-
DefaultJobParametersConverter
-
Spring Batchが提供する。
-
パラメータのデータ型は
java.io.Serializable
を実装した任意のJavaBeansを指定できる。
-
-
JobParametersConverterImpl
-
Macchinetta Batch 2.xが提供する。もともとSpring Batchで提供していたJsrJobParametersConverterを、JSR-352の廃止に伴いMacchinetta Batch 2.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
が使用される。
しかし、Macchinetta Batch 2.xでは以下の理由によりDefaultJobParametersConverter
は採用しない。
-
1つのジョブを同じパラメータによって、異なるタイミングで起動することは一般的である。
-
起動時刻のタイムスタンプなどを指定し、異なるジョブとして管理することも可能だが、それだけのためにジョブパラメータを指定するのは煩雑である。
-
DefaultJobParametersConverter
はパラメータに対しデータ型を指定することができるが、型変換に失敗した場合のハンドリングが煩雑になる。
Macchinetta Batch 2.xでは、JobParametersConverterImpl
を利用することで、ユーザが意識することなく自動的にRUN_IDを付与している。
この仕組みにより、ユーザから見ると同一ジョブをSpring Batchとしては異なるジョブとして扱っている。
ブランクプロジェクトでは、あらかじめTerasolunaBatchConfiguration.java/launch-context.xml
にてJobParametersConverterImpl
を使用するように設定している。
そのためMacchinetta Batch 2.xを推奨設定で使用する場合はJobParametersConverter
の設定を行う必要はない。
@Configuration
@Import(TerasolunaBatchConfiguration.class)
@PropertySource(value = "classpath:batch-application.properties")
public class LaunchContextConfig {
// omitted
@Bean
public JobParametersConverter jobParametersConverter(
@Qualifier("adminDataSource") DataSource adminDataSource) {
return new JobParametersConverterImpl(adminDataSource);
}
@Override
@Bean
public JobOperator jobOperator() throws BatchConfigurationException {
JobOperatorFactoryBean jobOperatorFactoryBean = new JobOperatorFactoryBean();
jobOperatorFactoryBean.setTransactionManager(
getTransactionManager());
jobOperatorFactoryBean.setJobRepository(jobRepository());
jobOperatorFactoryBean.setJobExplorer(jobExplorer());
jobOperatorFactoryBean.setJobRegistry(jobRegistry());
jobOperatorFactoryBean.setJobLauncher(jobLauncher());
JobParametersConverterImpl jobParametersConverter = new JobParametersConverterImpl(
getDataSource());
jobOperatorFactoryBean.setJobParametersConverter(
jobParametersConverter); // (1)
try {
jobParametersConverter.afterPropertiesSet();
jobOperatorFactoryBean.afterPropertiesSet();
return jobOperatorFactoryBean.getObject();
} catch (BatchConfigurationException e) {
throw e;
} catch (Exception e) {
throw new BatchConfigurationException(
"Unable to configure the customized job operator", e);
}
}
<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" <!-- (1) -->
p:jobLauncher-ref="jobLauncher" />
項番 | 説明 |
---|---|
(1) |
jobOperatorのjobParametersConverterの設定 |
以降はJobParametersConverterImpl
を利用する前提で説明する。
コマンドライン引数から与える
まず、もっとも基本的な、コマンドライン引数から与える方法について説明する。
コマンドライン引数としてCommandLineJobRunner
の第3引数以降に<パラメータ名>=<値>
形式で列挙する。
パラメータの個数や長さは、Spring BatchやMacchinetta Batch 2.xにおいては制限がない。
しかし、OSにはコマンド引数の長さに制限がある。
そのため、あまりに大量の引数が必要な場合は、ファイルから標準入力へリダイレクトするや
パラメータとプロパティの併用などの方法を活用すること。
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
com.example.batch.jobs.JobDefinedConfig.JobDefinedConfig JOBID param1=abc outputFileName=/tmp/result.csv
$ # 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の なお、 |
Stepスコープの定義方法
Spring Batchのlate bindingを使用してJobParametersを参照するreaderやwriterは ジョブのBean定義にはジョブの構成要素による定義とジョブから呼ばれるコンポーネントの2種類あり、それぞれの定義場所や定義方法は異なる。
現状、コンポーネントに |
@Bean
@StepScope // (1)
public FlatFileItemReader<SalesPlanDetail> reader(
@Value("#{jobParameters['inputFile']}") File inputFile) { // (2)
// omitted
}
<!-- (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 \
com.example.batch.jobs.JobDefinedConfig.JobDefinedConfig JOBID < params.txt
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
JobDefined.xml JOBID < params.txt
パラメータの参照方法はコマンドライン引数から与える方法と同様である。
パラメータのデフォルト値を設定する
パラメータを任意とした場合、以下の形式でデフォルト値を設定することができる。
-
#{jobParameters['パラメータ名'] ?: デフォルト値}
ただし、パラメータを使用して値を設定している項目であるということは、デフォルト値もパラメータと同様に環境や実行タイミングによって異なる可能性がある。
まずは、デフォルト値をソースコード上にハードコードをする方法を説明する。 しかし、後述のパラメータとプロパティの併用を活用する方が適切なケースが多いため、合わせて参照。
該当するパラメータが設定されなかった場合にデフォルト値に設定した値が参照される。
@Bean
@StepScope // (1)
public FlatFileItemReader<SalesPlanDetail> reader(
@Value("#{jobParameters['inputFile'] ?: '/input/sample.csv'}") File inputFile) { // (2)
// omitted
}
<!-- (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
を提供している。
このバリデータでは設定により以下を検証することができる。
-
必須パラメータが設定されていること
-
必須または任意パラメータ以外のパラメータが指定されていないこと
以下に定義例を示す。
@Configuration
@Import(JobBaseContextConfig.class)
@ComponentScan(value = "org.terasoluna.batch.functionaltest.ch04.jobparameter", scopedProxy = ScopedProxyMode.TARGET_CLASS)
public class JobDefaultJobParametersValidatorConfig {
// (1)
@Bean
public DefaultJobParametersValidator jobParametersValidator() {
return new DefaultJobParametersValidator(
new String[] {"jsr_batch_run_id", "inputFileName", "outputFileName"}, // (2), (3)
new String[] {"param1", "param2"}); // (4)
}
@Bean
public Step step01(JobRepository jobRepository,
@Qualifier("jobTransactionManager") PlatformTransactionManager transactionManager,
RefWithDefaultInJavaTasklet tasklet) {
return new StepBuilder("jobDefaultJobParametersValidator.step01", jobRepository)
.tasklet(tasklet, transactionManager)
.build();
}
@Bean
public Job jobDefaultJobParametersValidator(JobRepository jobRepository,
Step step01,
DefaultJobParametersValidator jobParametersValidator) {
return new JobBuilder("jobDefaultJobParametersValidator",
jobRepository)
.start(step01)
.validator(jobParametersValidator) // (5)
.build();
}
}
<!-- (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
public DefaultJobParametersValidator jobParametersValidator() {
return new DefaultJobParametersValidator(
new String[] {"outputFileName"},
new String[] {"param1"});
}
<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 \
com.example.batch.jobs.JobDefinedConfig JOBID param1=aaa
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
JobDefined.xml JOBID param1=aaa
必須パラメータoutputFileName
が設定されていないためNGとなる。
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
com.example.batch.jobs.JobDefinedConfig.JobDefinedConfig JOBID outputFileName=/tmp/result.csv
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
JobDefined.xml JOBID outputFileName=/tmp/result.csv
必須パラメータoutputFileName
が設定されるためOKとなる。任意パラメータparam1
は設定されていなくてもよい。
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
com.example.batch.jobs.JobDefinedConfig.JobDefinedConfig JOBID param1=aaa outputFileName=/tmp/result.csv
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
JobDefined.xml JOBID param1=aaa outputFileName=/tmp/result.csv
必須パラメータoutputFileName
が設定されるためOKとなる。
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
com.example.batch.jobs.JobDefinedConfig.JobDefinedConfig JOBID fileoutputFilename=/tmp/result.csv param2=aaa
$ # Execute job
$ java org.springframework.batch.core.launch.support.CommandLineJobRunner \
JobDefined.xml JOBID fileoutputFilename=/tmp/result.csv param2=aaa
必須パラメータoutputFileName
が設定されるためOKとなる。Bean定義にないパラメータparam2
が設定されてもよい。
複雑な妥当性検証
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) |
パラメータ |
@Bean
public Step step01(JobRepository jobRepository,
@Qualifier("jobTransactionManager") PlatformTransactionManager transactionManager,
RefWithDefaultInJavaTasklet tasklet) {
return new StepBuilder("jobDefaultJobParametersValidator.step01", jobRepository)
.tasklet(tasklet, transactionManager)
.build();
}
@Bean
public Job jobDefaultJobParametersValidator(JobRepository jobRepository,
Step step01,
DefaultJobParametersValidator jobParametersValidator) {
return new JobBuilder("jobDefaultJobParametersValidator",
jobRepository)
.start(step01)
.validator(jobParametersValidator) // (1)
.build();
}
<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 \
com.example.batch.jobs.JobDefinedConfig.JobDefinedConfig JOBID param3=ccc outputFile=/tmp/result.csv
$ # 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 \
com.example.batch.jobs.JobDefinedConfig.JobDefinedConfig JOBID param1=bbb outputFile=/tmp/result.csv
$ # 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が設定されてしまうため注意すること。 誤ったデフォルト値の設定方法例
|