S-JIS[2015-12-13/2016-07-31] 変更履歴

Asakusa Framework Direct I/OでWordCount

Asakusa Framework0.7.6のDirect I/Oおよび拡張機能を使ってWordCountを作ってみた。


概要

AsakusaFWの標準の機能だけを使ったWordCountに対し、標準以外の機能も使ったWordCountを作ってみた。

標準以外の機能とは、以下のものである。


WordCountプロジェクトの作成

前提:EclipseにShafuおよび拙作DMDL EditorXが入っていること。

  1. プロジェクト作成(Shafuの新規プロジェクト作成機能を使用する)
    1. Eclipseのメニューバーの「File」→「New」→「Gradleプロジェクトをテンプレートから生成」を選択し、ダイアログを開く。
    2. 「新規プロジェクト情報」ページで、プロジェクト名を入力する。
      今回の例では「wordcount2」とする。
    3. 「プロジェクトテンプレートの生成」ページでテンプレートを選択する。
      1. 「URLを指定してプロジェクトテンプレートをダウンロードする」を選択し、右側の「選択」ボタンを押す。
        1. 「Asakusa Project Template」の最新バージョン(0.7.6以降)を選択する。
      2. 「Gradleの設定」の「プロジェクトをインポートする前にビルドを実行する」にチェックを付けておく。
    4. 「Finish」ボタンを押すと、プロジェクトが作成される。
  2. build.gradleの修正
    1. 拡張機能およびテストドライバーでスモールジョブ実行エンジンを使用する設定を追加する。
      repositories {
          maven { url 'http://hishidama.github.io/mvnrepository' }
      }
      
      dependencies {
          compile group: 'com.asakusafw.sdk', name: 'asakusa-sdk-core', version: asakusafw.asakusafwVersion
          compile group: 'com.asakusafw.sdk', name: 'asakusa-sdk-directio', version: asakusafw.asakusafwVersion
          compile group: 'com.asakusafw.sdk', name: 'asakusa-sdk-windgate', version: asakusafw.asakusafwVersion
          compile group: 'com.asakusafw.sandbox', name: 'asakusa-directio-dmdl-ext', version: asakusafw.asakusafwVersion
          compile group: 'jp.hishidama.asakusafw', name: 'asakusafw-spi', version: '0.+'
      
          testRuntime group: 'com.asakusafw.sdk', name: 'asakusa-sdk-test-emulation', version: asakusafw.asakusafwVersion
          testRuntime group: 'jp.hishidama.asakusafw', name: 'asakusafw-tester', version: '0.+'
      〜
      }
      asakusa-directio-dmdl-extは、AsakusaFW 0.7.5〜0.8.0でdirectio.lineを使う為に必要。0.8.1以降では不要。[2016-07-31]
    2. Eclipseプロジェクトを更新する。
      1. パッケージエクスプローラー上でプロジェクト名「wordcount2」を右クリックし、メニューの「Jinrikisha(人力車)」→「Eclipseプロジェクト情報を再構成」 を実行する。
  3. フローのテスト環境の作成
    1. 事前に環境変数ASAKUSA_HOMEを定義し、Asakusa Frameworkをインストールする場所を指定しておく。
    2. パッケージエクスプローラー上でプロジェクト名「wordcount2」を右クリックし、メニューの「Jinrikisha(人力車)」→「Asakusa開発環境の構成」→「Asakusa Frameworkのインストール」を実行する。

テンプレート

最初に、Importer/Exporterクラスのテンプレートを作っておく。
(このテンプレートのファイル名をDMDL上に記述する為)

テンプレートファイルは(dmdlの場所に合わせて)src/main/templateの下に置くこととする。
テンプレートにはFreeMarkerというテンプレートエンジンが使われているので、拡張子はftlとする。

今回は、Importerはdirectio.line(テキストファイル読み込み用)、Exporterはdirectio.csv(CSVファイル出力用)のテンプレートを作成する。

src/main/template/FromLine.ftl

package ${packageName};

/**
 * ${model.description!""}
 */
public class ${className} extends Abstract${model.camelName}LineInputDescription {

	@Override
	public String getBasePath() {
		return "master/${model.name}";
	}

	@Override
	public String getResourcePattern() {
		return "*.csv";
	}

	@Override
	public DataSize getDataSize() {
		return DataSize.${arg("dataSize")!"UNKOWN"};
	}
}

src/main/template/ToCsv.ftl

package ${packageName};

/**
 * ${model.description!""}
 */
public class ${className} extends Abstract${model.camelName}CsvOutputDescription {

	@Override
	public String getBasePath() {
		return "result/${model.name}";
	}

	@Override
	public String getResourcePattern() {
		return "${model.name}.csv";
	}
}

見ればなんとなく分かる通り、「${変数名}」で変数が使用できる。
${変数名!値}」は、変数がnullだった場合に「!」以降で指定された値が出力される。

また、「<#タグ>」でFreeMarker用の構文も使える。

テンプレートを使って実際に生成されたクラス(javaソース)


モデル

入力データ・出力データを表すクラス(モデル)を作成する。

今回は入力ファイルにdirectio.lineを使うので、入力行を表す1項目だけがあるデータモデルを作成する。
出力は単語と個数というCSVファイルとする。
中間のデータモデルとして、1行のテキストを分割した単語のみを表すデータモデルも用意する。


ここではmodels.dmdlというファイルを作成し、データモデルを記述する。

WordCountであれば、入力は単なる文字列(text)、出力は単語(word)と出現数(count)。

wordcount2/src/main/dmdl/models.dmdl:

"テキストファイルの一行に対応するエンティティ"
@directio.line
@template(
  id = "fromLine",
  template = "src/main/template/FromLine.ftl",
  category = "line",
  type_name_pattern = "{0}FromLine",
  args = { "dataSize=LARGE" }
)
line_model = {

    "テキスト"
    text : TEXT;
};

word_model = {

    "単語"
    word : TEXT;
};

"単語と発生回数の対を表現するエンティティ"
@directio.csv
@template(
  id = "toCsv",
  template = "src/main/template/ToCsv.ftl",
  category = "csv",
  type_name_pattern = "{0}ToCsv"
)
summarized word_count_model = word_model => {

    "単語"
    any word -> word;

    "発生回数"
    count word -> count;
} % word;

「@template」でテンプレートファイルの場所やファイル名・引数を指定する。

@templateの引数
属性名 説明
id ひとつのデータモデルに複数の@templateを付ける場合、それぞれを区別するためのもの。
区別がつきさえすれば、適当な文字列でよい。
template テンプレートファイルのパス。プロジェクトディレクトリーからの相対パス。
category 生成されるソースのパッケージ名の一部に使われる。
type_name_pattern 生成されるクラス名。「{0}」の部分はデータモデルクラス名に置換される。
args テンプレート内で使う値。
args = { "引数名=値" }」と書くと、テンプレート側で「${arg("引数名")}」で値が取れる。

作成したDMDLファイルからデータモデルクラス(Javaソース)を生成する。

Shafuを使う場合は以下のようにして生成する。

  1. パッケージエクスプローラー上でプロジェクト(wordcount2)を選択し、右クリックしてコンテキストメニューを出す。
  2. 「Jinrikisha(人力車)」→「DMDLからデータモデルクラスを作成」を実行する。

あるいは、DMDL EditorXを使う場合は以下のようにする。

  1. パッケージエクスプローラー上でプロジェクト内のファイルを(適当に)選択する。
  2. ツールバーの「Asakusa FrameworkのDMDLコンパイラーを起動してJavaクラスを生成」ボタンを押す。

これにより、@directio.lineや@directio.csv属性が付けられたデータモデルのImporter/Exporterの抽象クラスが生成される。
また、@template属性に従ったクラスも生成される。


ちなみに、テンプレートによって作られたクラスは以下のようになっている。

build/generated-sources/modelgen/com/example/modelgen/dmdl/line/LineModelFromLine.java:

package com.example.modelgen.dmdl.line;

/**
 * テキストファイルの一行に対応するエンティティ
 */
public class LineModelFromLine extends AbstractLineModelLineInputDescription {

	@Override
	public String getBasePath() {
		return "master/line_model";
	}

	@Override
	public String getResourcePattern() {
		return "*.csv";
	}

	@Override
	public DataSize getDataSize() {
		return DataSize.LARGE;
	}
}

build/generated-sources/modelgen/com/example/modelgen/dmdl/csv/WordCountModelToCsv.java:

package com.example.modelgen.dmdl.csv;

/**
 * 単語と発生回数の対を表現するエンティティ
 */
public class WordCountModelToCsv extends AbstractWordCountModelCsvOutputDescription {

	@Override
	public String getBasePath() {
		return "result/word_count_model";
	}

	@Override
	public String getResourcePattern() {
		return "word_count_model.csv";
	}
}

@directio.line・@directio.csvによって作られる抽象クラスを継承しているが、その抽象クラスと同じパッケージに属すようにcategoryを付けたので、import文は無くても大丈夫。


オペレーター(演算子)

次に、オペレーター(演算子)を作成する。

Operatorのテスト


オペレーターはJavaの抽象クラス内に定義する決まりになっているので、最初に空のクラスを作る。

src/main/java/com/example/operator/WordCountOperator.java

package com.example.operator;

public abstract class WordCountOperator {

}

テキストを単語に分割するには、Extract(抽出演算子)を使う。

import java.util.StringTokenizer;

import com.asakusafw.runtime.core.Result;
import com.asakusafw.vocabulary.operator.Extract;
import com.example.modelgen.dmdl.model.LineModel;
import com.example.modelgen.dmdl.model.WordModel;
	private final WordModel wordModel = new WordModel();

	@Extract
	public void split(LineModel line, Result<WordModel> out) {
		String text = line.getTextAsString();

		StringTokenizer tokenizer = new StringTokenizer(text);
		while (tokenizer.hasMoreTokens()) {
			String word = tokenizer.nextToken();

			wordModel.reset();
			wordModel.setWordAsString(word);

			out.add(wordModel);
		}
	}

Operatorクラスでは、メソッド名がジョブフローで使えるメソッド名(AsakusaDSL的には“語彙”と呼ばれる)になる。
Resultの変数名は、ジョブフローでの出力フィールド名になる。
(デフォルトで用意されている演算子(core演算子)では、出力が1つの場合はoutという名前になっている事が多いので、それを踏襲した)

DMDL上でTEXTとして宣言した項目は、Javaのクラス上はHadoopのTextクラスになっている。
そしてセッター・ゲッターには「asString」という接尾辞が付いたメソッドが用意されているので、Stringクラスで読み書きできる。


DMDLでsummarizedを使った場合、ジョブフローで使えるメソッド名(語彙)を決める為に(だと思う)、OperatorクラスにSummarize演算子(メソッド名と入出力のデータモデルクラス)を記述する。

import com.asakusafw.vocabulary.flow.processor.PartialAggregation;
import com.asakusafw.vocabulary.operator.Summarize;
import com.example.modelgen.dmdl.model.WordCountModel;
import com.example.modelgen.dmdl.model.WordModel;
	@Summarize(partialAggregation = PartialAggregation.PARTIAL)
	public abstract WordCountModel count(WordModel in);

集計方法自体はDMDLの方に書かれているので、Operatorのメソッドとしては特に記述するものは無い。
したがって抽象メソッドになっている。

SummarizeにPARTIALを指定すると、部分集約(中間集計)が行われる(つまりCombinerが動く)ようになる。


Operatorのソースを記述して保存すると、EclipseのAsakusaFWプラグイン(Ashigelコンパイラー)が自動的に起動して、FactoryクラスやOperatorImplクラスを生成する。
(DMDLと違って、何らかのコマンドを実行する必要は無い)
もしエラーがあったら、通常のEclipseでのコンパイルエラーと同様にソース上に赤い印が出る。


オペレーター(演算子)のテスト

オペレーター(演算子)は実行時に普通に呼び出されるクラスなので、単体テストは普通にJUnit4で直接メソッドを呼び出す形で行う。

が、今回はメソッド呼び出し部分に拙作のテストツールを使ってみる。
このテストツールでは、Operatorの演算子の種類に応じたTesterクラスを使用する。

src/test/java/com/example/operator/WordCountOperatorTest.java:

package dio.wordcount.operator;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

import java.util.ArrayList;
import java.util.List;

import jp.hishidama.asakusafw.tester.ExtractTester;
import jp.hishidama.asakusafw.tester.OperatorTester.OperatorResults;

import org.junit.Test;

import com.example.modelgen.dmdl.model.LineModel;
import com.example.modelgen.dmdl.model.WordModel;
public class WordCountOperatorTest {

	@Test
	public void testSplit() {
		ExtractTester tester = new ExtractTester(WordCountOperator.class, "split");

		// 入力データ
		List<LineModel> list = new ArrayList<>();
		list.add(createText("word1"));
		list.add(createText(""));
		list.add(createText("word3 blank"));
		list.add(createText("word4 blank"));
		list.add(createText("word5\ttab"));
		list.add(createText("word6\t tab-blank"));
		list.add(createText("word7\ttab blank"));

		// テスト実行
		OperatorResults result = tester.execute(list);
		List<WordModel> out = result.get(0);

		// 結果確認
		String[] expected = { "word1", "word3", "blank", "word4", "blank", "word5", "tab", "word6", "tab-blank", "word7", "tab", "blank" };
		assertThat(out.size(), is(expected.length));
		int i = 0;
		for (WordModel word : out) {
			assertThat(word.getWordAsString(), is(expected[i++]));
		}
	}

	LineModel createText(String text) {
		LineModel model = new LineModel();
		model.setTextAsString(text);
		return model;
	}
}

testerのインスタンス生成時に、テスト対象のOperatorクラス名とメソッド名を渡す。
(内部でOperatorImplのインスタンスが生成される)

通常のOperatorのテストの場合、OperatorImplクラスのメソッドを直接呼ぶ形になるが、
拙作のテストツールの場合、入力データのリストを渡し、出力結果のリストを受け取る形になる。
(Extract演算子だと直接メソッドを呼ぶ形式の方がテストしやすいかもしれないが、元々このテストツールは、入力データのソートやグルーピングが必要となる演算子(GroupSortやMasterJoin等)のテストをする目的で作った)


countメソッドは抽象メソッドであり、実体はAsakusaFWが生成するので、通常は単体テストの対象外。
OperatorImplでのcountメソッドの実装は、例外が発生するようになっている(使えないようになっている)。

が、集計モデルのキーが正しいのかどうかテストしたければ、拙作のテストツールで@Summarizeのメソッドをテストすることも出来る。[2015-12-23]

import jp.hishidama.asakusafw.tester.SummarizeTester;

import com.example.modelgen.dmdl.model.WordCountModel;
import com.example.modelgen.dmdl.model.WordModel;
	@Test
	public void testCount() {
		SummarizeTester tester = new SummarizeTester(WordCountOperator.class, "count");

		// 入力データ
		List<WordModel> list = new ArrayList<>();
		list.add(createWord("Hello"));
		list.add(createWord("World"));
		list.add(createWord("Hello"));
		list.add(createWord("Asakusa"));

		// テストの実行
		List<WordCountModel> out = tester.execute(list);

		// 結果確認
		assertThat(out.size(), is(3));

		Map<String, Long> map = new HashMap<>();
		for (WordCountModel model : out) {
			map.put(model.getWordAsString(), model.getCount());
		}
		assertThat(map.get("Hello"), is(2L));
		assertThat(map.get("World"), is(1L));
		assertThat(map.get("Asakusa"), is(1L));
	}

	WordModel createWord(String word) {
		WordModel model = new WordModel();
		model.setWordAsString(word);
		return model;
	}

ジョブフロー

次に、ジョブフローを定義する。
ここで「どのファイルを入力とし、どのオペレーターを呼んで、どのファイルへ出力するか」を記述する。

参考: Asakusa FrameworkのAsakusa DSLスタートガイド#データフローを記述する

ジョブフローのテスト


Importer/Exporterクラス

通常であれば、まずImporter/Exporterクラスを作成するのだが、今回はテンプレートによって生成されているので、何もしなくてよい。


Flowクラス

今回は、DMDL EditorXの機能を使ってジョブフロークラスを作ってみる。

  1. パッケージエクスプローラー上でプロジェクト内のファイルを適当に選択する。
    (本来はジョブフロークラスを作成したいパッケージを選択するのが良いのだが、現時点ではまだ作られていないので適当なファイルを選択する)
  2. ツールバーあるいは右クリックのコンテキストメニューの「New JobFlow class」を実行すると、ウィザードが起動する。
  3. 最初にクラス名を入力する。
    項目 説明
    Source folder ソースのディレクトリー。 wordcount2/src/main/java
    Package パッケージ名。 com.example.jobflow
    Name クラス名。 WordCountJob
  4. 次に、ジョブフロー名と説明を入力する。
    項目 説明
    comment ジョブフローの日本語名。
    クラスやコンストラクターのJavadocに使われる。
    ワードカウントジョブ
    JobFlow name ジョブフロー名。
    @JobFlow(name="ジョブフロー名")」として使われる。
    個人的には、クラス名と同じ名前にしてしまっている。
    WordCountJob
  5. そのジョブで使用するImporter/Exporterを指定する。
    Importerを追加する場合は「add Imp」、Exporterを追加する場合は「add Exp」ボタンを押し、Importer/Exporterクラスを選択する。
    「adds」ボタンを押すと、全Importer/Expoterから複数のクラスを選択できるが、クラスが大量にある場合はダイアログが出るまでかなり遅くなる(数分かかる)ことがあるので注意。
  6. 「Finish」ボタンを押すと、ジョブフロークラスが生成される。

src/main/java/com/example/jobflow/WordCountJob.java

package com.example.jobflow;

import com.asakusafw.vocabulary.flow.Export;
import com.asakusafw.vocabulary.flow.FlowDescription;
import com.asakusafw.vocabulary.flow.Import;
import com.asakusafw.vocabulary.flow.In;
import com.asakusafw.vocabulary.flow.JobFlow;
import com.asakusafw.vocabulary.flow.Out;
import com.example.modelgen.dmdl.csv.WordCountModelToCsv;
import com.example.modelgen.dmdl.line.LineModelFromLine;
import com.example.modelgen.dmdl.model.LineModel;
import com.example.modelgen.dmdl.model.WordCountModel;
/**
 * ワードカウントジョブ
 */
@JobFlow(name = "WordCountJob")
public class WordCountJob extends FlowDescription {

	/** テキストファイルの一行に対応するエンティティ */
	private final In<LineModel> lineModel;
	/** 単語と発生回数の対を表現するエンティティ */
	private final Out<WordCountModel> wordCountModel;
	/**
	 * ワードカウントジョブ
	 * 
	 * @param lineModel テキストファイルの一行に対応するエンティティ
	 * @param wordCountModel 単語と発生回数の対を表現するエンティティ
	 */
	public WordCountJob(
		@Import(name = "lineModel", description = LineModelFromLine.class) In<LineModel> lineModel,
		@Export(name = "wordCountModel", description = WordCountModelToCsv.class) Out<WordCountModel> wordCountModel
	) {
		this.lineModel = lineModel;
		this.wordCountModel = wordCountModel;
	}
	@Override
	public void describe() {
		// TODO WordCountJob.describe()
	}
}

describeメソッドの中は自分で書く必要がある。

import com.example.operator.WordCountOperatorFactory;
import com.example.operator.WordCountOperatorFactory.Count;
import com.example.operator.WordCountOperatorFactory.Split;
	@Override
	protected void describe() {
		WordCountOperatorFactory operators = new WordCountOperatorFactory();

		Split split = operators.split(lineModel);
		Count count = operators.count(split.out);
		wordCountModel.add(count.out);
	}
}

operators.split()やoperators.count()が、自分で作ったオペレーター(演算子)を表している。

split.outの「out」は、Extractを使って自分で記述したメソッドの引数のResultの変数名


ジョブフロークラス上で右クリックしてコンテキストメニューを開き、「DMDL EditorX」→「Modify JofFlow/FlowPart Field」を実行すると、
ジョブフロークラスを作ったときと同様のウィザードで、コンストラクターの引数およびフィールドを編集(追加・削除)することが出来る。

ただし、編集されたフィールドやコンストラクターはインデントが無茶苦茶になってしまうので、Ctrl+Shift+Fでソース整形することを推奨する。


ジョブフローのテスト

AsakusaFWでは、ジョブフロー(とFlowPartとバッチ)のテスト用クラスが用意されている。
それらを使ってJUnit4として実行できる。(今回はスモールジョブ実行エンジンでテストを実行するよう最初に設定してある)

今回は、DMDL EditorXの機能を使ってジョブフローのテストクラスおよびテストデータ用Excelファイルを生成してみる。

  1. パッケージエクスプローラー上でジョブフロークラスを選択する。
  2. 右クリックのコンテキストメニューの「DMDL EditorX」→「New JobFlow/FlowPart Test class」を実行すると、ウィザードが起動する。
  3. 最初にソースディレクトリーやパッケージ名・クラス名を入力するが、大抵はデフォルトのままでいいはず。
  4. 次に、Excelのデータ用シートの一覧を指定する。
    入出力に使っているデータモデルがデフォルトで全て出ているので、大抵はこのままでいいと思う。
  5. 最後に、作成するExcelファイルのファイル名や作成するシート名を指定する。
    デフォルトでは、ジョブフローテストクラス名と同一のExcelファイル名が指定され、そのExcelファイルの中に全データを入れる形になっている。
    (通常のAsakusaFWの場合は、データモデル毎に別々のExcelファイルを使うようになっている)

src/test/java/com/example/jobflow/WordCountJobTest.java

package com.example.jobflow;

import com.asakusafw.testdriver.JobFlowTester;
import com.asakusafw.testdriver.core.PropertyName;
import com.example.jobflow.WordCountJob;
import com.example.modelgen.dmdl.model.LineModel;
import com.example.modelgen.dmdl.model.WordCountModel;
import org.junit.Test;
/**
 * {@link WordCountJob}のテスト。
 */
public class WordCountJobTest {

	static {
		System.setProperty(PropertyName.KEY_SEGMENT_SEPARATOR, "_");
	}
	@Test
	public void describe() {
		JobFlowTester tester = new JobFlowTester(getClass());
		// TODO tester.setBatchArg("arg", "value");

		tester.input("lineModel", LineModel.class).prepare("WordCountJobTest.xls#lineModel");
		tester.output("wordCountModel", WordCountModel.class).verify("WordCountJobTest.xls#wordCountModel", "WordCountJobTest.xls#wordCountModel_rule");

		tester.runTest(WordCountJob.class);
	}
}

この状態で、Ctrlキーを押しながらExcelファイル名の部分をマウスでホバーするとメニューが出る。
そこで「Open File」を選択すると、そのExcelファイルを開くことが出来る。
(src/test/resource下の同一パッケージ内にそのExcelファイルがあるときだけ使える技(笑))


このExcelファイルに対し、入力データおよび検証データを記載する。

参考: Asakusa FrameworkのExcelによるテストデータ定義

lineModelシート(入力データ):

  A B C
1 text    
2 Hello Hadoop World    
3 Hello Asakusa    
4      
5      

wordCountModelシート(検証データ):

  A B C
1 word count  
2 Asakusa 1  
3 Hadoop 1  
4 Hello 2  
5 World 1  
6      

wordCountModel_ruleシート(検証ルール):

  A B C D E F
1 Format EVR-2.0.0        
2 全体の比較 全てのデータを検査 [Strict]        
3 プロパティ 値の比較 NULLの比較 コメント オプション  
4 word 検査キー [Key] 通常比較 [-] 単語    
5 count 完全一致 [=] 通常比較 [-] 発生回数    
6            

検証データシートに書かれているデータと実際のデータをどう比較してどういう状態ならテストOK(あるいはNG)とするかをruleシートに書く。
どのセルも初期値は自動で入っている。

今回のケースでは出力項目がwordとcountの二項目なので、それぞれどういう比較をするかを書く。(書くというか、実際はプルダウンになっているので、選択する)

※ExcelファイルをEclipse外のエディターで編集したら、Eclipse上でF5を押して反映させる(srcからclassesへコピーさせる)必要がある。

Excelファイルを使用せず、独自のデータを入力データにする方法


バッチ

最後にBatch DSLで「どのジョブフローを実行するか」を記述する。

今回は、DMDL EditorXの機能を使ってバッチクラスを作ってみる。

  1. パッケージエクスプローラー上でプロジェクト内のファイルを適当に選択する。
    (本来はバッチクラスを作成したいパッケージを選択するのが良いのだが、現時点ではまだ作られていないので適当なファイルを選択する)
  2. ツールバーあるいは右クリックのコンテキストメニューの「New Batch class」を実行すると、ウィザードが起動する。
  3. 最初にクラス名を入力する。
    項目 説明
    Source folder ソースのディレクトリー。 wordcount2/src/main/java
    Package パッケージ名。 com.example.batch
    Name クラス名。 WordCountBatch
  4. 次に、バッチ名およびバッチ引数の定義を入力する。
    項目 説明
    comment バッチの日本語名。
    クラスのJavadocや@Batchのコメントに使われる。
    ワードカウントバッチ
    Batch name バッチ名。
    @Batch(name="バッチ名")」として使われる。
    つまり、YAESSの引数として使用するもの。
    個人的には、クラス名と同じ名前にしてしまっている。
    WordCountBatch
    parameter バッチ引数がある場合、その定義。
    ここを書かなくても実行は出来る。
     
  5. 最後に、バッチ内のジョブフローを指定する。
    ここで書かなくても後でdescribeメソッドの中を自分で書けばいいが、ジョブフローを1つ実行するバッチなら、ここでジョブフロークラスを指定してしまう方が楽。

src/main/java/com/example/batch/WordCountBatch.java:

package com.example.jobflow;

import com.asakusafw.vocabulary.batch.Batch;
import com.asakusafw.vocabulary.batch.BatchDescription;
import com.example.jobflow.WordCountJob;
/**
 * ワードカウントバッチ
 */
@Batch(
	name = "WordCountBatch",
	comment = "ワードカウントバッチ",
	strict = false)
public class WordCountBatch extends BatchDescription {

	@Override
	public void describe() {
		run(WordCountJob.class).soon();
	}
}

WordCountへ戻る / AsakusaFW目次へ戻る / 技術メモへ戻る
メールの送信先:ひしだま