システム開発で思うところ

JavaEEを主にシステム開発をしながら思うところをツラツラを綴る

Pluggable Annotation Processing API Sample(実践編3)

vermeer.hatenablog.jp

vermeer.hatenablog.jp

実践1で挙げた課題について対応しました。

コマンドの記述が繁雑
実行ライブラリのクラスパスにprocessor-command.xmlを配置しないといけないません。つまり利用側が自分のresources配下に機能一覧を追記したprocessor-command.xmlを配置しないといけません。最低でも提供側が定義ファイルに記述する内容をルートパッケージのJavaDocなどに記載したり、手引きに書いておかないと、何をどうしたら良いのかわかりません

Pluggable Annotation Processing API Sample(実践編1) - システム開発で思うところ

今回の対応でprocessor-command.xmlが任意のオプショナルなものになりました。

利用の手引き

  1. Annotation Processorが実行できるpom.xmlの設定
  2. Command Class を実装
  3. コンパイル時にAnnotation Processorにより実行される(※)

※ プロジェクトのクラスパスリソース直下のprocessor-command.xmlにより、実行時の制御ができます(任意).


pom.xml 記述

利用ライブラリとして、またAnnotation Processorを実行する設定をするためにpom.xmlを編集します.

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>

    <!-- Maven Repository on GitHub  start -->
    <git.branchName>mvn-repo</git.branchName>
    <git.repositoryOwner>vermeerlab</git.repositoryOwner>
    <git.repositoryName>maven</git.repositoryName>
    <!-- Maven Repository on GitHub  end-->
</properties>

<repositories>
    <!-- Maven Repository on GitHub  start -->
    <repository>
        <id>org.vermeerlab</id>
        <url>https://raw.github.com/${git.repositoryOwner}/${git.repositoryName}/${git.branchName}/</url>
        <snapshots>
            <enabled>true</enabled>
            <updatePolicy>always</updatePolicy>
        </snapshots>
    </repository>
    <!-- Maven Repository  on GitHub  end-->
</repositories>

<dependencies>
    <dependency>
        <groupId>org.vermeerlab</groupId>
        <artifactId>annotation-processor-core</artifactId>
        <version>0.3.0</version> <!-- target version -->
    </dependency>
</dependencies>

<build>
    <plugins>

        <!-- for annotation processor start-->
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.0</version>
            <configuration>
                <source>${maven.compiler.source}</source>
                <target>${maven.compiler.target}</target>
                <!-- Disable annotation processing for ourselves. -->
                <compilerArgument>-proc:none</compilerArgument>
                <compilerArgs>
                    <arg>-Xlint</arg>
                </compilerArgs>
                <showDeprecation>true</showDeprecation>
            </configuration>
        </plugin>
        <!-- annotation processor end -->
    </plugins>
</build>

Command Class の実装

AnnotationProcessorがorg.vermeerlab.apt.command.ProcessorCommandInterface、またはorg.vermeerlab.apt.command.PostProcessorCommandInterfaceを実装したクラスをコンパイル時に検索して実行します.

2つのインターフェースの違い

  • ラウンド毎に処理(ProcessorCommandInterface
  • ラウンド毎の処理に加えて、最終ラウンドに処理(PostProcessorCommandInterface

proseccor-command.xml の設定(任意)

ファイルが存在しない場合(デフォルト)

  • コンソールに実行コマンドは表示しません
  • 全ての.classファイル および、jarファイルを検索対象とします

ファイルが存在する場合

processor-command.xmlの設定により、以下の対応が可能です.

  • 実際に実行しているコマンドクラスを確認をコンソールに出力
  • 適用したくないコマンドクラスの除外
  • クラスパス配下のファイルだけを対象にして、jarを対象外
  • 検索対象のjarファイルを指定

詳細は xmlコメントを参照してください.

<?xml version="1.0" encoding="UTF-8"?>
<!--
Annotation Processor で実行するコマンドを登録する設定ファイルです.
コマンドクラスは
org.vermeerlab.apt.command.ProcessorCommandInterface
を実装してください.

全ラウンドで まとめて行うコマンドは
org.vermeerlab.apt.command.PostProcessorCommandInterface
を実装してください.
-->
<root>
    <!--
    実行コマンドリストを標準出力制御を設定してください.
    出力する場合は true.
    デフォルトは false(出力しない)
    -->
    <displayCommandList>true</displayCommandList>

    <!--
    実行対象外とするコマンドクラスの完全修飾名を設定してください.
    -->
    <excludeCommands>
        <excludeCommand>
        </excludeCommand>
    </excludeCommands>

    <!--
    コマンドクラスの検索対象としてクラスパス配下のJarファイルを読み込み有無を設定してください.
    Jarファイルを読み込む場合は true
    -->
    <scanJarFile>true</scanJarFile>

    <!--
    コマンドクラスの検索対象とするクラスパス配下のJarファイルを設定してください.
    -->
    <scanTargetJarFiles>
        <scanTargetJarFile>
        </scanTargetJarFile>
    </scanTargetJarFiles>

</root>

例えば、どんなコマンドが実行されているのか、確認するために いったん <displayCommandList>trueにして確認をした上で、不要なコマンドを <excludeCommands>で除外をすると無駄がありません。
その上で、<scanTargetJarFiles>で使用するコマンドのjarだけを検索対象とすればコンパイル時の性能影響も最小限に留めることができます。

Code

BitBucket バージョン 0.3.0

さいごに

当初、諦めていたことが出来たというだけでも個人的には満足です。それに加えて 使用者が自分だけでも暗黙の手順が不要になったことを素直に嬉しく思います。

次回は、今回のライブラリを利用した具体的な事例として、JavaPoetを使用してJavaコードを生成するライブラリについて記事が書ければと思っています。