仕事でJava 8とJava 11を行ったり来たりしたり、Javaの特定のマイナーバージョンでのみ発生する問題の調査などをしないといけないケースが出てきて、最初は都度環境変数で切り替えていたのですが、切り替え忘れてうっかり別のバージョンでコンパイルしてしまうということが増えてきたのでjenvというツールを試してみました。
$ brew install jenv
jenvはデフォルトでは~/.jenv
に設定などを保存するようです。以下のディレクトリを手動で作成しておく必要がありました。*1
$ mkdir -p ~/.jenv/versions
.bash_profile
などに以下を追加。
eval "$(jenv init -)"
JDKはbrew 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でインストールすることはできません。
jenvでJDKのディストリビューションの区別がつかない問題、gitの最新のmasterでは修正されていてjenv addでちゃんとprovider付きのエイリアスも登録されるようになっていた。若干メンテが止まっている気配があるけどせめて新しいバージョンをリリースして欲しいなぁ。 pic.twitter.com/PYOAcyLkL5
— Naoki Takezoe (@takezoen) May 16, 2020