概要
DomaはPluggable Annotation Processing APIを用いてDAOの実装クラスやエンティティの補助クラスをコンパイル時に自動生成します。
Domaによって自動生成されるのはJavaファイルですが、MavenやGradleで普通に(?)紹介されている方法(下記のリンク先を参照)でソースJARを作っても自動生成されたJavaファイルはソースJARに含まれません。
- https://maven.apache.org/plugin-developers/cookbook/attach-source-javadoc-artifacts.html
- https://docs.gradle.org/current/userguide/publishing_maven.html#publishing_maven:complete_example
テーブルと1対1にマッピングされるエンティティはDoma-Genで生成してJARにまとめてWebプロジェクトやバッチプロジェクトから参照するといった構成にすることがあると思いますが、その際にエンティティのソースJARにDomaによって自動生成されるJavaファイルも含めたいというモチベーションがあります。
ここではMavenとGradleそれぞれどうすればDomaによって自動生成されるJavaファイルをソースJARに含むことができるのかを記載します。
Maven
MavenでソースJARを作るにはorg.apache.maven.plugins:maven-source-plugin
のjar
ゴールを実行します。
パッケージングの対象がsrc/main/java
とsrc/main/resources
のようなので、そこにDomaによって自動生成されるJavaファイルの出力先ディレクトリを追加すれば良さそうです。
そう考えてjar
ゴールのドキュメントを見たのですが、パッケージングの対象を追加できそうなオプションが見当たりませんでした。
仕方がないのでjar
ゴールの実装であるSourceJarMojoを見ました。
SourceJarMojo
はSourceJarNoForkMojoを継承していました。
SourceJarNoForkMojo
の中でソースディレクトリ(パッケージングの対象)を取得している箇所を見ると、MavenProject#getCompileSourceRoots()
が呼ばれています。
MavenProject#getCompileSourceRoots()のJavadocを見ても何も書かれていませんでしたが、クラス名などから察するにプロジェクト全体に関わる設定のようです。
以上のことからDomaによって自動生成されるJavaファイルの出力先をリソースディレクトリとして追加することにしました。
<resources>
<resource>
<filtering>false</filtering>
<directory>src/main/resources</directory>
</resource>
<resource>
<filtering>false</filtering>
<!--
Pluggable Annotation Processing APIが生成するソースコードのデフォルト出力先を
リソースディレクトリに追加することでsources-jarに含める。
https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#generatedSourcesDirectory
-->
<directory>${project.build.directory}/generated-sources/annotations</directory>
</resource>
</resources>
ただ、MavenはリソースのコピーをしてからコンパイルしてJARにパッケージングするので、何度かmvn package
をすると2回目以降のJAR(ソースJARではなく、クラスファイルがパッケージングされている方のJAR)にDomaによって自動生成されたJavaファイルもパッケージングされてしまいます。
そのため、org.apache.maven.plugins:maven-jar-plugin
の設定でJavaファイルはパッケージに含めない設定を追加しました。
<!--
ソースディレクトリをリソースに追加したのでJARファイルに
Javaファイルを含めないようにする。
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</configuration>
</plugin>
これであとはmvn package source:jar
とするだけです。
Gradle
GradleはMavenと違ってソースJARを作るプラグインがあるわけではなく、Jar
タスクをベースに自分でソースJARを作るタスクを定義します。
そのときにパッケージ対象のディレクトリへDomaによって自動生成されるJavaファイルの出力先を追加すれば良いです。
GradleではDomaによって自動生成されるJavaファイルの出力先はsourceSets.main.output.classesDirs
がデフォルトです。
これはクラスファイルの出力先でもあるので、クラスファイルを除く設定も書きます。
task sourcesJar(type: Jar) {
from sourceSets.main.allJava, sourceSets.main.output.classesDirs //Domaが生成するソースはsourceSets.main.output.classesDirsに出力される
classifier = 'sources'
exclude '**/*.class' //sourceSets.main.output.classesDirsはclassファイルも含むのでフィルタリングする
}
前述の通り、Domaによって自動生成される(というかPluggable Annotation Processing APIを使って生成される)Javaファイルはクラスファイルと同じ場所に出力されます。
そのためデフォルトでJARファイルにJavaファイルがパッケージングされてしまうので、それを除く設定を追加します(なんでデフォルトでそんな場所に出力されるのか、、、)。
//sourceSets.main.output.classesDirsに出力されるJavaファイルを除く
jar.excludes = ['**/*.java']
これであとはgradle build sourcesJar
とするだけです。
終わりに
動くコード例は次の場所に置いています。
ソースJARをローカルのNexusにデプロイするところまで体験できるようにしています。