GeekFactory

int128.hatenablog.com

GradleでAPT (Annotation Processing Tool) を使う

GradleでAPTを使うにはAntのaptタスクを利用します。slim3-genをどうやって組み込むか小一時間悩んだので残しておきます。

やり方は色々あると思います。私は以下の方針でやってみました。

  • 新しいソースセット(apt)を定義します。
  • APTコンパイルタスク(compileAptJava)を定義します。
    • タスクの入力はプロダクトコード(sourceSets.main.java.srcDirs)
    • タスクの出力はAPT出力(sourceSets.apt.output.resourcesDir)
    • ant.aptではプリプロセスだけでコンパイルは実行しません。APT出力はプロダクトコードのコンパイルタスクでコンパイルします*1
  • プロダクトコードにAPT出力を追加します。
  • プロダクトコードのコンパイルタスク(compileJava)にはAPTコンパイルタスク(compileAptJava)が必要と定義します。

build.gradle の抜粋です。

sourceSets {
  apt
}

dependencies {
  aptCompile ('org.slim3:slim3-gen:1.0.15') {
    exclude group: 'org.apache.ant'
  }
}

task compileAptJava(overwrite: true) << {
  // 出力先が存在しないとant.aptがエラーになる
  sourceSets.apt.output.resourcesDir.mkdirs()
  // ant.aptにfactorypathを直接渡せないのでID渡し
  ant.path(id: 'aptFactoryPath', location: configurations.aptCompile.asPath)
  ant.apt(compile: false,
    includeAntRuntime: false,
    factorypathref: 'aptFactoryPath',
    classpath: configurations.compile.asPath,
    preprocessdir: sourceSets.apt.output.resourcesDir,
    encoding: 'UTF-8') {
    sourceSets.main.java.srcDirs.each{
      src(path: it)
    }
  }
}

compileAptJava.inputs.dir  sourceSets.main.java.srcDirs
compileAptJava.outputs.dir sourceSets.apt.output.resourcesDir

compileJava.dependsOn compileAptJava
sourceSets.main.java.srcDirs += sourceSets.apt.output.resourcesDir  // ★追記参照

★8/21追記 最後の行は以下のように書いた方がいいです。ソースディレクトリを書き換えると他のタスク(例えばコード分析)に影響を及ぼしてしまうため、コンパイルタスクの入力に入力に追加する方が安全です。

compileJava.source sourceSets.apt.output.resourcesDir

★8/21追記 slim3-genの依存関係が抜けていたので記載しました。

Antのaptタスクはaptコマンドを利用します。Java6からはaptコマンドではなく javac -proc:only -processorpath が推奨されているようですが、slim3-gen はこの方法をサポートしていないので試せていません。参考まで。

*1:ant.aptでプリプロセスに加えてコンパイルまで実行する方法もあります。その場合、APT出力はクラスファイルとなります。