追記 2021-02-14
Toolchains はまだ IDEA ではサポートされてないみたい。IDEA を使うときはこれまでの書き方をしておく方が良さそう。
Support detecting SDKs from Gradles toolchain support https://youtrack.jetbrains.com/issue/IDEA-252328
追記ここまで ===
昨日、Gradleのことを書いたのだけど。そういえば、触ってる中でもうひとつ学んだことがあったので、今日はそれについて。今日もタイトルの通り。
昨日も書いたけど、Gradleって変化が速い印象あるので、しばらくするとこのやり方よりも良いやり方が出てくるかもしれない。今日は、2021年2月時点のGradle 6.8.2のお話。
これまでの書き方
これまでは、Gradleでビルドに使うJavaのバージョンを指定するのには sourceCompatibility
と targetCompatibility
を使ってた。実際に、昨日の最後に出てきたやつは、Gradleの公式サイトから落としてきたやつなんだけど、こうなってる:
❯ cat build-logic/commons/src/main/groovy/com.example.commons.gradle ... java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } ...
こういう設定でコンパイルしたclassファイルのバージョンをみるとJava 8のになってる:
❯ javap -v app/build/classes/java/main/toolchains/sample/App.class | grep major major version: 52
Toolchainsを使う
これを、Toolchainsを使うように変更する:
java { toolchain { languageVersion = JavaLanguageVersion.of(11) } }
Toolchainsを使うとどうなるの?
Toolchainsは
- 指定されたバージョンがないかをローカルマシーンの中で探す
- 見つからなかったらダウンロードする
- それを使ってくれる
この辺りを読んだ。
https://docs.gradle.org/6.8.2/userguide/toolchains.html
https://blog.gradle.org/java-toolchains
遊んでみよう
こういう build.gradle
を用意してみた:
plugins { id 'application' } repositories { mavenCentral() } application { mainClass = 'toolchains.sample.App' }
実行するJavaのバージョンを出してみようかな。App.java
をこうしてみる。
package toolchains.sample; public class App { public static void main(String[] args) { System.out.println(System.getProperty("java.version")); System.out.println(System.getProperty("java.home")); } }
実行
❯ ./gradlew run > Task :app:run 15.0.2 /home/bufferings/.sdkman/candidates/java/15.0.2.hs-adpt BUILD SUCCESSFUL in 1s 2 actionable tasks: 2 executed
いまAkkaで遊んでて 15.0.2
をデフォルトにしてるから、それが使われてる。
バージョンを指定してみる
java { toolchain { languageVersion = JavaLanguageVersion.of(11) } }
実行
❯ ./gradlew run // こんな感じでダウンロードされた <=============> 100% CONFIGURING [4s] > Provisioning toolchain adoptopenjdk-11-x64-linux.tar.gz > adoptopenjdk-11-x64-linux.tar.gz > Task :app:run 11.0.10 /home/bufferings/.gradle/jdks/jdk-11.0.10+9 BUILD SUCCESSFUL in 2s 2 actionable tasks: 2 executed
ほほー。homeの.gradleの下に入るのか。便利。バージョンも上がってる↓
❯ javap -v app/build/classes/java/main/toolchains/sample/App.class | grep major major version: 55
既存のJDKを使う
指定したバージョンのJDKが、既にSDKMAN!でインストール済みの場合は、そっちが使われるんかな?14は入ってるから試してみる。
❯ ./gradlew run > Task :app:run 14.0.1 /home/bufferings/.sdkman/candidates/java/14.0.1.hs-adpt BUILD SUCCESSFUL in 2s 2 actionable tasks: 2 executed
ほほー。賢い。
ということで
Toolchainsを使うと、使いたいJDKがインストールされていない環境でも、ダウンロードしてきてビルドを実行してくれる。最初にダウンロードの時間はかかるけど。便利。