Posted at

Kotlin の kapt を IntelliJ IDEA で動かしたい (Gradle プロジェクト)

More than 1 year has passed since last update.

手探りでいろいろ試したり調べたりしていきついた方法を書いてます。 もっといい方法がある気がするからなんかあったら教えてください。 (Android Studio における Android アプリ開発だと kapt をもっといい感じに扱えてる気がするけどそっちについては特に調べてない。)


まとめ


  • Kotlin 1.0.5-2 時点では IntelliJ IDEA による直接の kapt サポートはないぽい。


    • IntelliJ IDEA 2016.3、Kotlin plugin 1.0.5-release-IJ2016.3-2 で試した。



  • JetBrains の人的には 「Gradle プロジェクトなら Gradle タスクを実行して kapt を使ってね」 という感じっぽい。

  • IntelliJ IDEA から Gradle タスクを実行する方法としては以下のようなものがある。


    • Gradle ツールウィンドウなどから明示的にタスクを実行する。

    • ビルド実行前に指定の Gradle タスクを実行するように設定する。

    • IntelliJ IDEA におけるビルドや実行を全て Gradle に委譲するように設定する。



  • Gradle タスクによる kapt で生成されたソースコードを IntelliJ IDEA が認識できるように設定しよう。


背景

先日、Dagger 2 を使っている Java プロジェクトを IntelliJ IDEA でビルドする (アノテーションプロセッシングも行う) 方法についてまとめた。

このプロジェクトに Kotlin を導入して、Kotlin のアノテーションプロセッシングツール kapt を使って Gradle でのビルドは問題なくできるようになったものの、IntelliJ IDEA にていい感じに扱う方法がわからなかったので調べた。


現時点では IntelliJ IDEA (および Kotlin Plugin) による直接の kapt サポートはない

ないらしい。 JetBrains の人が言ってる。


Raman.Gupta :

How can I get the Kotlin annotation processor to run from IJ?

"Enable annotation processors" in Settings does not seem to work.

yole (JetBrains Team) :

This is currently unsupported. What's your use case? Why can't you use Gradle to build your project?


(「Execute kapt/kapt2 from within IJ - Kotlin Discussions」 より)

Gradle でビルドできないん? って言ってるから JetBrains の人的には Gradle でビルドするのが普通っぽい?


というわけで Gradle タスクを使う


IntelliJ IDEA から Gradle タスクを実行する方法

IntelliJ IDEA で Gradle タスクを実行する方法を 3 つ書いておく。 IntelliJ IDEA 2016.3 時点での設定である。


Gradle ツールウィンドウから明示的に実行する

Gradle ツールウィンドウから、「Tasks」 → 「build」 → 「assemble」 を選択して実行すれば kapt も走る。 ショートカットキーも設定できるので、開発中に何度も明示的に実行するならショートカットキーを割り当てておくとよい。


ビルド前に指定の Gradle タスクを実行するように設定する

Gradle ツールウィンドウから、「Tasks」 → 「build」 → 「assemble」 を右クリックし、「Execute Before Build」 を有効にすると、IntelliJ IDEA でビルドする際に Gradle の assemble タスクが実行されるようになる。 IntelliJ IDEA 側と Gradle 側で二重にビルドが走ってしまうのがつらいところではあるが、kapt が有効になる。

毎回明示的に実行するのは面倒なので、自分は今のところこの方法を使っている。


ビルドと実行を Gradle に委譲するように設定する

設定の 「Build, Execution, Deployment」 → 「Build Tools」 → 「Gradle」 → 「Runner」 で 「Delegate IDE build/run actions to gradle」 にチェックを入れる。

これで問題なく開発できるならこれが一番まともな気がする? 自分のプロジェクト (web アプリケーション) では、「実行中のプロセスを再実行した際に、再実行前のプロセスの終了に時間がかかっていて、同じポートにバインドしようとしてエラーになってしまう」 という問題があったのでこの方法は採らないことにした。


生成されるソースコードをソースフォルダとして追加しよう

あと、Gradle タスクによる kapt で生成されたソースコードを IntelliJ IDEA が認識できるように設定する必要がある。 「Project Structure」 からモジュールを選択し、「build/generated/source/kapt/main」 をソースディレクトリとして追加しよう。 (テストでも kapt を使う場合はテストの方も。) kapt 2 を使っている場合は 「kapt」 の部分が 「kapt2」 になる。

ちなみに IntelliJ IDEA 2016.1 からは、デフォルトでソースセットごとにモジュールが分かれているので、「Add Content Root」 でディレクトリごと content root として追加する必要がある。 (プロジェクトのインポート時に 「Create separate module per source set」 のチェックを外していれば、普通にディレクトリを選択するだけでいけるはず。)

intellij.png


ちなみに build.gradle はどんなん?

今更だけど build.gradle を貼っておく。 以下のような build.gradle を書けば Kotlin を使ったプロジェクトで Dagger を使えるはず。

buildscript {

ext.kotlin_version = '1.0.5-2'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

apply plugin: 'java'
apply plugin: 'kotlin'

group 'com.example.kotlin.kapt'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8
targetCompatibility = 1.8

def defaultEncoding = 'UTF-8'
tasks.withType(JavaCompile)*.options*.encoding = defaultEncoding

repositories {
mavenCentral()
}

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}

kapt {
generateStubs = true
}

dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

compile 'com.google.dagger:dagger:2.8'
kapt 'com.google.dagger:dagger-compiler:2.8'
}


その他参考にしたページ

kapt 周りがよくわかんなかったので調べたときに参考になったページ。