Mojoを作成する

Mavenプラグインの実体は、Mojo(Maven plain Old Java Object)と呼ばれるクラスです。Mavenプラグインは含まれるゴールの数だけMojoを保有します。 このクラスに必要なメソッドとMojoアノテーションを追加することでプラグインの実装を行います。

MojoはAbstractMojoを継承し、@Mojoアノテーションで修飾される必要があります。 また@Executeアノテーションや@Parameterアノテーション、@Componentアノテーションなどorg.apache.maven.plugins.annotationsパッケージに用意されたアノテーションを使用することもできます。

以下にシンプルなMojoの実装を記載します。

import java.io.File;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

@Mojo(
        name = "sample",
        threadSafe = true,
        defaultPhase = LifecyclePhase.COMPILE
)
public class SampleMojo extends AbstractMojo {
    @Parameter(
            property = "project.build.directory",
            required = true
    )
    private File outputDirectory;

    @Override
    public void execute() throws MojoExecutionException {
        getLog().info("sample plugin start!");
        getLog().debug("project.build.directory is " + outputDirectory.getAbsolutePath());
    }
}

順を追って見ていきましょう。

呼び出されるメソッドを実装する

Mavenプラグインが実行されると、Mojoのexecuteメソッドが実行されます。 プラグインの実際の処理はここに記載します。

実行するフェーズを指定する

@MojoアノテーションのdefaultPhaseオプションによって、実行するフェーズを指定することができます。 この設定はユーザの設定によって上書くことが可能ですが、デフォルト設定で多くの環境で問題なく動作することが望ましいでしょう。

設定を作成する

プラグインは様々なプロジェクトに対応するため、しばしば設定を提供します。 設定はpom.xmlに記載することができるため、同じ設定を複数の環境で容易に共有することができます。 一般的な設定としては以下があります。`

  • <skip> ... trueならプラグインの実行を行いません。プロジェクト固有のプロパティで指定できることもあります。
  • <outputDirectory> ... 成果物の出力先ディレクトリです。project.build.directoryプロパティが示すディレクトリ、あるいはそのサブディレクトリをデフォルト値として使用するべき1です。
  • <encoding> ... ファイルの読み書きに利用するエンコードです。project.build.sourceEncodingプロパティをデフォルト値として使用できます。

ログを出力する

Mavenプラグインを実装する場合、ログの出力は標準出力や標準エラー出力ではなく、親クラスが提供するロガーを利用します。 これによって、Mavenの-qオプション(エラーのみ出力)や-Xオプション(デバッグログ出力)やログの接頭辞に準拠でき、ログの可読性が向上します。

getLog().info( "This is info  level, Maven will print this if user does not use -q option.");
getLog().debug("This is debug level, Maven will print this if user uses -X option.");
getLog().error("This is error level, Maven will print this even if user uses -q option.");

処理を高速化するため、デバッグ時にのみ情報を取得・計算することもできます。

if (getLog().isDebugEnabled()) {
  getLog().debug(computeDetailedLogMessage());
}

なお引数に渡す文字列には、改行コードを含めないことをおすすめします。接頭辞がつかない行ができてしまい、 機械的に処理することが難しくなるためです。複数行の出力を行いたい場合は、メソッドを複数回に分けて 呼び出してください。

マルチスレッド対応の明示

もし作成したプラグインがスレッドセーフである場合は、それを明示することが望ましいと言えます。 Maven3.5.0時点でのマルチスレッドサポートは限定的ですが、これが改善されたときのために用意しておきましょう。

@MojoアノテーションのthreadSafeプロパティによってスレッドセーフか否かを表現できます。 公式のチェックリストを確認し、スレッドセーフであると言える場合は、trueを指定しましょう。

@Mojo(
        name = "sample",
        threadSafe = true
)

2015年4月時点での公式チェックリストの訳を以下に記載します。

  • staticなフィールドや変数を使っている場合、その値がスレッドセーフであることを確認すること。
    • 特に "java.text.Format" のサブクラス (NumeberFormat, DateFormat など) はスレッドセーフでないので、staticなフィールドを介して複数のスレッドから利用されるようなことがないように注意する。
  • components.xmlにシングルトンとして定義されているPlexusコンポーネントを使っている場合、そのコンポーネントはスレッドセーフでなければならない。
  • 依存ライブラリに既知の問題が存在しないか確認すること。
  • サードパーティ製ライブラリがスレッドセーフであることを確認すること。

つまり、単一JVM内で複数のMojoインスタンスが並列に作成・実行される可能性があるので、それに備える必要があるということです。

動作確認

ここまで来たら、作ったプラグインが正常に動作することを確認してみましょう。 ローカルリポジトリにプラグインをインストールしてから、作成したMojoを実行してみてください。

mvn clean install
mvn jp.skypencil:sample-maven-plugin:sample
mvn jp.skypencil:sample-maven-plugin:help
1. "target"などとハードコードすると、ユーザがproject.build.directoryプロパティを変更した際に動作しなくなります。

results matching ""

    No results matching ""