mike-neckのブログ

Java or Groovy or Swift or Golang

sdkman で複数のバージョンの Java をディレクトリーごとに切り替える

複数のプロジェクトを行ったり来たりする際に、プロジェクトごとに Java のバージョンが違っている際は、たいてい IntelliJ が覚えていてくれるので、それほど困ってはいないのですが、世の中にはターミナルでなんでもこなす人がいるらしく、プロジェクトごとに Java のバージョンを設定するツールが求められているらしいです。いわゆる env 系ツール(renvnodenv)ですが、それの Java 版の jenv というものがあるようです。

takezoe.hatenablog.com

ざっとドキュメントを見たところでは「特定のディレクトリのみこのバージョンを使う」という設定ができるかどうかわかりませんでした。

ということのようですが、つい先程、 sdkman でもそのようなニーズに答えるようになったようです。

env Command

というわけで、 バージョン 5.8.1 から使える env の動作を確認してみようと思ったのですが

f:id:mike_neck:20200505075414p:plain

このブログを書いている時点ではまだ更新できませんでしたが、すでに env コマンドが搭載されているようなので試してみることにしました。

まずは foobar というディレクトリーを作ります。

$ mkdir foo bar

foo ディレクトリーでは、 Javasdk でデフォルトに設定されているバージョンを使うようにします。

$ 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.

これで、 java20.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(例えば gradlespringbootsbt など)もバージョンを指定できるのではないかと推測されます。

そこで、 gradle6.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.

おっと、インストールしてくれるかと思いきや、インストールしてくれませんね。この辺は今後に期待ですね。


f:id:mike_neck:20200505074742p:plain