[備忘録][GCP][Datastore] datastorecallbacks.xml を Maven で出力する

# 1. はじめに

この記事は Google Cloud Platfrom (GCP) の Datastore 処理のフック呼び出し(データストア コールバック)の設定が定義された構成ファイル『datastorecallbacks.xml』を Maven で出力する方法の備忘録になります。
事の発端は App Engine アプリケーションのソースコードを Maven でパッケージビルドした時に、datastorecallbacks.xml ファイル が期待する場所(*～/WEB-INF/classes/META-INF*)に（正確にはどの場所にも）出力されていないことに気づいたからですが、これを解決するための情報が見つからず、とても苦労しました。
私と同様にハマる人がいるかもしれないと思いましたので、記録としてここに書き残します。

なお、データストア コールバックの内容についてはここでは説明しません。詳細については以下サイトをご覧ください。

データストアでのコールバック &nbsp;|&nbsp; Java 8 の App Engine スタンダード環境 &nbsp;|&nbsp; Google Cloud
https://cloud.google.com/appengine/docs/legacy/standard/java/datastore/callbacks?hl=ja

なお、わざわざ言わなくてもお分かりいただけると思いますが、今回の記事はかなりニッチな内容になっています（私の記事はどれもニッチな内容ですけれど）。

# 2. 調査

datastorecallbacks.xml は Java ソースコードファイルに定義されたの特定のアノテーション(`@PrePut` や `@PostLoad` 等)を元に作成されます。ということは、まず最初にそのアノテーションを処理するプロセッサクラスを明らかにしなければ対処できないと考えました。

答えにたどり着くまでに紆余曲折ありましたが、そのあたりの話は割愛して、求めるプロセッサクラスは [DatastoreCallbacksProcessor](https://github.com/GoogleCloudPlatform/appengine-java-standard/blob/main/api/src/main/java/com/google/appengine/tools/compilation/DatastoreCallbacksProcessor.java) になります。
ちなみにこのクラスは **appengine-api-1.0-sdk-x.x.x.jar**（x.x.x はバージョン番号） にあります。

# 3. pom.xml の定義

プロセッサクラスが分かったので、次は datastorecallbacks.xml ファイルを出力するための定義を Maven の設定ファイル pom.xml に追加してみます。
アノテーションを元にコードを作成する仕組みといえば Annotation Processing Tool (APT)、Maven で APT を扱うには「apt-maven-plugin」ということで、apt-maven-plugin プラグインを使ってファイルを出力してみます。

```xml:pom.xml (該当部分のみ抜粋)
    <build>
        <plugins>
            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <id>apt-dsc</id>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.outputDirectory}</outputDirectory>
                            <compilerOptions>
                                <d>${project.build.outputDirectory}</d>
                            </compilerOptions>
                            <processors>
                                <processor>com.google.appengine.tools.compilation.DatastoreCallbacksProcessor</processor>
                            </processors>
                        </configuration>
                    </execution>
                </executions>
        </plugins>
    </build>
```

ポイントは
```xml
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<compilerOptions>
    <d>${project.build.outputDirectory}</d>
</compilerOptions>
```
の箇所になります。

通常、apt-maven-plugin でファイルの出力先を指定するときは `<outputDirectory>` 要素のみを定義すれば事足りるのですが、**DatastoreCallbacksProcessor の場合は上手くいきません**。`<outputDirectory>` にどんな値を指定しても、datastorecallbacks.xml ファイルはプロジェクトディレクトリの直下に出力されました。
そこで、`<compilerOptions>` 要素で Java のコンパイラにも出力先を渡すようにしています。そうすることで、*～/WEB-INF/classes/META-INF* に datastorecallbacks.xml ファイルが出力されるようになります。

ちなみに、`<compilerOptions>` 要素の定義だけでもよさそうに見えますが、`<outputDirectory>` 要素の定義を削除すると今度はファイル出力自体が行われなくなるため、いずれの定義も必要なようです。

# 4. おわりに

こんなニッチな内容の記事を読んでいただき、ありがとうございます:relaxed:
次回もニッチな内容になると思います（たぶん）。


# 5. 参考にさせていただいた情報

Class DatastoreCallbacksProcessor (2.0.0) &nbsp;|&nbsp; Google App Engine standard environment docs &nbsp;|&nbsp; Google Cloud
https://cloud.google.com/appengine/docs/standard/java-gen2/reference/services/bundled/latest/com.google.appengine.tools.compilation.DatastoreCallbacksProcessor

GitHub - querydsl/apt-maven-plugin: Maven APT plugin
https://github.com/querydsl/apt-maven-plugin