複数のプロジェクトを行ったり来たりする際に、プロジェクトごとに Java のバージョンが違っている際は、たいてい IntelliJ が覚えていてくれるので、それほど困ってはいないのですが、世の中にはターミナルでなんでもこなす人がいるらしく、プロジェクトごとに Java のバージョンを設定するツールが求められているらしいです。いわゆる env 系ツール(renv 、 nodenv)ですが、それの Java 版の jenv というものがあるようです。
ざっとドキュメントを見たところでは「特定のディレクトリのみこのバージョンを使う」という設定ができるかどうかわかりませんでした。
ということのようですが、つい先程、 sdkman でもそのようなニーズに答えるようになったようです。
SDKMAN 5.8.1 is rolling out, featuring the new `sdk env` command for switching SDKs per project. Thanks to @helpermethod for his contribution! https://t.co/ZEQaFx6bpD
— SDKMAN! (@sdkman_) 2020年5月4日
というわけで、 バージョン 5.8.1 から使える env の動作を確認してみようと思ったのですが

このブログを書いている時点ではまだ更新できませんでしたが、すでに env コマンドが搭載されているようなので試してみることにしました。
まずは foo と bar というディレクトリーを作ります。
$ mkdir foo bar
foo ディレクトリーでは、 Java を sdk でデフォルトに設定されているバージョンを使うようにします。
$ cd foo $ sdk env init .sdkmanrc created
この .sdkmanrc というファイルには <candidate>=<version> という形式で設定が書かれています。
$ cat .sdkmanrc java=14.0.0-open
このバージョンをターミナルで有効化するには env コマンドを実行します。
$ sdk env Using java version 14.0.0-open in this shell.
次に bar ディレクトリーでは GraalVM の最新バージョン(Java 8)である 20.0.0-r8-grl を使うようにします。
$ cd ../bar
$ sdk env init
.sdkmanrc created.
$ echo "java=`sdk l java | grep grl | grep 20 | grep r8 | awk '{print $NF}'`"
java=20.0.0.r8-grl
$ echo "java=`sdk l java | grep grl | grep 20 | grep r8 | awk '{print $NF}'`" > .sdkmanrc
$ sdk env
Using java version 20.0.0.r8-grl in this shell.
これで、 java が 20.0.0.r8-grl に向くようになったので試してみます。
$ java --version Unrecognized option: --version Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit. $ java -version openjdk version "1.8.0_242" OpenJDK Runtime Environment (build 1.8.0_242-b06) OpenJDK 64-Bit Server VM GraalVM CE 20.0.0 (build 25.242-b06-jvmci-20.0-b02, mixed mode)
というわけで、 sdk env コマンドで切り替わったようです。
ところで、 java=20.0.0.r8-grl という書き方をしているところから、他の candidate(例えば gradle や springboot や sbt など)もバージョンを指定できるのではないかと推測されます。
そこで、 gradle の 6.2.2 をデフォルトで使うようにしてみます。
$ echo "gradle=6.2.2" >> .sdkmanrc $ sdk env Using java version 20.0.0.r8-grl in this shell. normalised_line='java=20.0.0.r8-grl' Using gradle version 6.2.2 in this shell. $ gradle --version ------------------------------------------------------------ Gradle 6.2.2 ------------------------------------------------------------ Build time: 2020-03-04 08:49:31 UTC Revision: 7d0bf6dcb46c143bcc3b7a0fa40a8e5ca28e5856 Kotlin: 1.3.61 Groovy: 2.5.8 Ant: Apache Ant(TM) version 1.10.7 compiled on September 1 2019 JVM: 11.0.6 (Oracle Corporation 11.0.6+9-jvmci-20.0-b02) OS: Mac OS X 10.15.4 x86_64
どうやら、 Java 以外の candidate のバージョンも指定可能なようです。
ローカルにしか存在しないバージョンを指定した場合はどうなるでしょうか?
例えば、お気づきのように今日(2020/05/05)現在、 Java の最新バージョンは 14.0.0 ではなく、 14.0.1 です。そこで、先程の foo ディレクトリーの Java のバージョンを 14.0.0-open から 14.0.1-open に変更してみます。
$ sed -i `s/0-/1-/g` $ sdk env Stop! java 14.0.1-open is not installed.
おっと、インストールしてくれるかと思いきや、インストールしてくれませんね。この辺は今後に期待ですね。
