jenvで複数バージョンのJDKを切り替える

仕事でJava 8とJava 11を行ったり来たりしたり、Javaの特定のマイナーバージョンでのみ発生する問題の調査などをしないといけないケースが出てきて、最初は都度環境変数で切り替えていたのですが、切り替え忘れてうっかり別のバージョンでコンパイルしてしまうということが増えてきたのでjenvというツールを試してみました。

github.com

Macの場合はbrewでインストールできます。

$ brew install jenv

jenvはデフォルトでは~/.jenvに設定などを保存するようです。以下のディレクトリを手動で作成しておく必要がありました。

$ mkdir -p ~/.jenv/versions

.bash_profileなどに以下を追加。

eval "$(jenv init -)"

JDKbrew caskでインストールできるようなのですが、手元にはすでにインストールしたものがあるのでとりあえずそれを追加してみます。

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (1):
    1.8.0_181, x86_64:  "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home

jenv addコマンドでjenvにJDKを認識させます。

$ jenv add /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home

手動でダウンロードしたGraalVMとJava 11も追加してみます。

$ jenv add /Users/takezoe/Downloads/graalvm-ce-java8-20.0.0/Contents/Home
$ jenv add /Users/takezoe/Downloads/amazon-corretto-11.jdk/Contents/Home

これで準備完了です。jenv versionsでjenvが認識しているJDKが一覧表示されます。GraalVMは普通のOpenJDKと区別が付かなくて紛らわしい感じがありますね…。

$ jenv versions
* system (set by /Users/takezoe/.jenv/version)
  1.8
  1.8.0.181
  1.8.0.242
  11.0
  11.0.7
  openjdk64-1.8.0.242
  openjdk64-11.0.7
  oracle64-1.8.0.181

jenv global <version>で使用するバージョンをグローバルに切り替えます。JDKのインストールは自分で行う必要がありますが、一度JDKを認識させてしませば使い勝手はpyenvやrbenvと同じような感じです。

$ jenv global 1.8.0.181

特定のディレクトリだけ別のバージョンを使用するには当該のディレクトリでjenv local <version>を実行します。この場合、ディレクトリに.java-versionというファイルが生成されます。このファイルをGitにコミットしておけばブランチごとに使用するJavaのバージョンが異なる場合でも自動で切り替えることができますね。

$ jenv global 11.0.7

jenvでのバージョン切り替えに応じて環境変数JAVA_HOMEも切り替えるには以下のコマンドを使用してexportプラグインを有効にしておく必要があるようです。

$ jenv enable-plugin export

SDKMANでも複数バージョンのJDKの切り替えができ、こちらはJDKのインストールもできるようですが、ざっとドキュメントを見たところでは「特定のディレクトリのみこのバージョンを使う」という設定ができるかどうかわかりませんでした。ひとまずjenvをしばらく使ってみようと思います。

追記:jenvでJDKディストリビューションの区別が付かないという問題は最新のmasterブランチでは修正されており、jenv addでprovider付きのエイリアスも登録されるようになっていました。ただ、この修正を含むバージョンはまだリリースされていないようで、Homebrewでインストールすることはできません。