IntelliJ IDEAとGradleタスクでコンパイラの出力先が異なる状態になることがある。自分の場合は、新規プロジェクトを作成して構築中は一致していたのだが、一旦git push
したものを改めてgit clone
してからIDEAに取り込んだ際に異なる状態になった。
- IDEAの出力先:
out/production
の配下のclasses
とresources
- Gradleの出力先:
build
配下のclasses
とresources
ちなみに、classes
はソースのコンパイル先であり、resources
はリソースファイルのコピー先である。
異なると何が問題かというと、gradleで実行したアプリケーションにおいて、ソースコードの変更を検知してAutoReloadしたい場合に、変更を検知できないことである。
ソースコード変更->IDEAでBuild->classファイルをIDEAに出力先に出力->アプリケーションのclass pathはGradleの出力先なので変更を検知できないという流れである。
この問題を回避するために、IDEAとGradleのコンパイラの出力先を一致させる必要がある。
方法1:IDEAの設定で出力先を変更する(部分的にしか解決しない)
IDEAのProject Structure
-> Modules
-> Paths
-> Compiler output
で、Use module compile output path
を選択し、Output pathをGradleの出力先と合わせる。
しかし、この方法だとソースのコンパイル先はbuild/classes
になりGradleと一致させられるのだが、リソースファイルの出力先はout/production
のままなので異なったままである。リソースファイルはAutoReload対象にしなくてもいいという人はこの方法で十分かもしれない。
なお、リソースファイルの出力先はIDEA場では個別に指定することはできなそうである(少なくとも自分は発見できなかった)。
ちなみに、Project Structure
-> Project
-> Project compiler output
をプロジェクトパス/build
に変更して、Module
-> Paths
-> Compiler output
をInherit project compile output path
にすることでうまくいきそうなものだが、残念なことにIDEAがbuild/production/
のように勝手にproduction
フォルダを作ってしまうため、Gardleの出力先と一致させることはできない。
方法2:IDEAでプロジェクト作成時にGradleプロジェクトとして作成する(解決する)
この方法で完全解決することは確認できているのだが、既存プロジェクトを取り込む際には普通はプロジェクトの新規作成は行わないので気づきにくい。
ここではgit clone
した既存プロジェクトを新規作成扱いで取り込む手順を記載する。
-
git clone
する -
Create New Project
を選択する。
Import Project
やOpen
は使わない
- Gradleプロジェクトとして作成する
-
GroupId
とArtifactId
に適当な値を設定する。
GroupId
は適当な値でOK。ArtifactId
は既存プロジェクトの名称と一致させる。
- Gradleプロジェクトの設定を行う。
User auto-import
はbuild.gradle
に変更があったら自動で依存関係などを解決してくれるというやつなので、好みで外してもいいと思う。
Create separate module per source set
はmain
とtest
を別モジュールとしてプロジェクトを作成してくれるというものなので、チェックしておいた方が良いと思う。
Use default gradle wrapper
も推奨なので設定しておいた方が良いと思われる。
-
git clone
したフォルダと一致するようにProject name
とProject location
を設定する
- そのまま作成を完了する
- 既存プロジェクトからの変更箇所を
git diff
で確認する
矢印の部分が勝手に作成された部分なので、この部分を削除する。
ちなみに、このプロジェクトでは.gitignore
に.idea
と.gradle
を設定済みなのでそこは差分として出ていない。もし設定してなかったら設定した方が良い。
- 変更箇所を削除する
git reset --hard master
で一発でやってもいいし、一つ一つ変更を破棄してもいいと思う。 - GradleのRefleshが走りProject Buildを実行すると、以下のように意図通りにコンパイル結果が出力される
方法3:Gradleの設定で出力先を変更する(解決する)
おそらくbuild.gradle
でGradleタスクのコンパイラ出力先をout/production
に変更するというのも、もう一つの解放になりえると思う。
compileJava {
buildDir = "out/production"
}
compileKotlin {
buildDir = "out/production"
}
sourceSets {
main {
output.resourcesDir = "out/production/resources"
}
}
この設定で試して見ると以下のようになる。
- Gradleタスクのソースコードのコンパイル先:
out/production/classes/kotlin/main/sample
- Gradleタスクのリソースファイルのコンパイル先:
out/production/resources
リソースファイルは想定通りだが、よく見るとソースコードの方は余計な階層kotlin/main
ができてしまっている。
これを解決するために、IDEAのProject Structure
-> Modules
-> Paths
-> Compiler output
で、Use module compile output path
を選択し、Output path
に
プロジェクトルート/out/production/classes/kotlin/main
を設定し、Gradleの出力先と合わせる必要がある。
この方法でも出力先を一致させることはできた。
しかし、build.gradle
とIDEAの二つの設定が必要になるので、方法2の方がまだマシな気がするので、私自身は方法2を採用した。