Mac+fish+jenv で複数Javaバージョン切り替え


注意

  • 備忘録です
  • 既存の情報と重複しています
  • 詳しい情報がほしい方はいつでもコメントでお申し付けください

やりたいこと

  • 個人でモダンな Java が使いたい(時代は Java11 なのだよ!!!)
  • 他人とのプロジェクトはやっぱ Java8
  • jenv 使えばそんなことができるらしい

環境

  • 実行日:2019/01/04
  • macOS Mojave 10.14.2
  • fish, version 3.0.0
  • Homebrew 1.8.6

シェルの記録

「やるべきこと」と「やらなくていいこと」が混じってます。
出力は一部省略されてます。

バージョン情報

⋊> ~ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.2
BuildVersion:   18C54
⋊> ~ fish -v
fish, version 3.0.0
⋊> ~ brew -v
Homebrew 1.8.6
Homebrew/homebrew-core (git revision 0857; last commit 2019-01-03)
Homebrew/homebrew-cask (git revision 89dd0; last commit 2019-01-03)

Homebrew Cask Versions をダウンロード

これが何をするもんなのか未だによくわかってないけどたぶん複数バージョンが使えるようになる魔法のパッケージです。

x> ~ brew tap caskroom/versions

お好きな Java をダウンロード

  • 2019年1月現在、各バージョンに対応する brew パッケージ名(全部 cask ですが)
    • java …… OpenJDK 11
    • java8 …… OracleJDK 8
    • java6 …… なんじゃこりゃ( support.apple.com とやらからダウンロードしてる)
    • java-beta …… OpenJDK 12 early access (すごい)
⋊> ~ brew cask install java java8

jenv を入れる

pyenvと同じようなものです。ってってもpyenv使ったことないんでよく知らないんですが。

⋊> ~ brew install jenv
🍺  /usr/local/Cellar/jenv/0.4.4: 78 files, 65.5KB, built in 6 seconds

🍺の絵文字出てくるのかわいい。

fish のためのアディショナルな設定

お魚さんの生育環境には特殊な設定が必要なのです。 http://www.jenv.be/ には書いてないし https://github.com/gcuisinier/jenv はびみょーに古い。この記事の存在意義はこのパートだけ。

jenv にパスを通す

brew が勝手にやってくれるんで必要ありません。

fish 用 jenv 関数の設定(?)

なんか jenv 使うにはマクロ的なのを登録する必要があるっぽい。いやなんで必要なのかよく知らんが。さてその fish 用のマクロ、いやスクリプト、関数って言ったほうがいいのかな、はどこにあるのやら

> ~ ls -al /usr/local/bin/jenv
lrwxr-xr-x  1 (中略)  admin  29  1  4 00:32 /usr/local/bin/jenv -> ../Cellar/jenv/0.4.4/bin/jenv

ふむふむ、fish の実態は /usr/local/Cellar/jenv/ あたりにありそうですね

⋊> ~ find /usr/local/Cellar/jenv/ | grep fish
/usr/local/Cellar/jenv//0.4.4/libexec/fish
/usr/local/Cellar/jenv//0.4.4/libexec/fish/export.fish
/usr/local/Cellar/jenv//0.4.4/libexec/fish/jenv.fish
⋊> ~ cat /usr/local/Cellar/jenv/0.4.4/libexec/fish/jenv.fish
set PATH $HOME/.jenv/shims $PATH
command jenv rehash 2>/dev/null
function jenv
  set cmd $argv[1]
  set arg ""
  if test (count $argv) -gt 1
    # Great... fish first array index is ... 1 !
    set arg $argv[2..-1]
  end

  switch "$cmd"
    case enable-plugin rehash shell shell-options
        set script (jenv "sh-$cmd" "$arg")
        eval $script
    case '*'
        command jenv $cmd $arg
    end
end

いたいた、たぶんこの jenv.fish ってやつをfishに登録してやればいいのか。
fish で使う関数は ~/.config/fish/functions/に置いてあげればいいようなので(Fish#Automaic Function

⋊> ~ mkdir -p ~/.config/fish/functions/
⋊> ~ cp /usr/local/Cellar/jenv/0.4.4/libexec/fish/jenv.fish ~/.config/fish/functions/

ええんちゃう?

ターミナルを再起動

たぶんこれで jenv は整備完了。

それではゴリゴリバージョンスイッチするぞい

自分が持ってる java 達の java_home を確認

⋊> ~ /usr/libexec/java_home -V
Matching Java Virtual Machines (2):
    11.0.1, x86_64: "OpenJDK 11.0.1"    /Library/Java/JavaVirtualMachines/openjdk-11.0.1.jdk/Contents/Home
    1.8.0_192, x86_64:  "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/openjdk-11.0.1.jdk/Contents/Home

一番下のは現在 path が通ってるやつ。たぶん。

jenv に登録

/usr/libexec/java_home -v {バージョン名} で必要なバージョンに該当する java_home が得られる。そいつを jenv add に渡してやる。

⋊> ~ jenv add (/usr/libexec/java_home -v 1.8)
oracle64-1.8.0.192 added
1.8.0.192 added
1.8 added
⋊> ~ jenv add (/usr/libexec/java_home -v 11)
openjdk64-11.0.1 added
11.0.1 added
11.0 added
⋊> ~ jenv versions
* system (set by /Users/(中略)/.jenv/version)
  1.8
  1.8.0.192
  11.0
  11.0.1
  openjdk64-11.0.1
  oracle64-1.8.0.192

いっぱい追加されました。わーい。
マイナーバージョンでもメジャーバージョンでも指定できるよってことですかね。

切り替えてみよう

⋊> ~ jenv global 1.8
⋊> ~ jenv versions
  system
* 1.8 (set by /Users/(中略)/.jenv/version)
  1.8.0.192
  11.0
  11.0.1
  openjdk64-11.0.1
  oracle64-1.8.0.192
⋊> ~ java -version
java version "1.8.0_192"
Java(TM) SE Runtime Environment (build 1.8.0_192-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.192-b12, mixed mode)
⋊> ~ javac -version                                                                                                                                                                                 01:26:14
javac 1.8.0_192
⋊> ~ jshell -version
Unable to locate an executable at "/Users/(中略)/.jenv/versions/1.8/bin/jshell" (-1)
⋊> ~ jenv global 11.0
⋊> ~ jenv versions
  system
  1.8
  1.8.0.192
* 11.0 (set by /Users/(中略)/.jenv/version)
  11.0.1
  openjdk64-11.0.1
  oracle64-1.8.0.192
⋊> ~ java -version
openjdk version "11.0.1" 2018-10-16
OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)
⋊> ~ javac -version
javac 11.0.1
⋊> ~ jshell -version
jshell 11.0.1
⋊> ~ jenv global system

切り替わってる感じがしていいですねえ。

⋊> ~ which java
/Users/(中略)/.jenv/shims/java
⋊> ~ which javac
/Users/(中略)/.jenv/shims/javac

なあるほどお。

⋊> ~ mkdir a
⋊> ~ cd a
⋊> ~/a jenv local 1.8
⋊> ~/a java -version
java version "1.8.0_192"
Java(TM) SE Runtime Environment (build 1.8.0_192-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.192-b12, mixed mode)
⋊> ~/a cd ..
⋊> ~ mkdir b
⋊> ~ cd b
⋊> ~/b jenv local 11.0
⋊> ~/b java -version
openjdk version "11.0.1" 2018-10-16
OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)
⋊> ~/b ls
⋊> ~/b ls -a
.             ..            .java-version
⋊> ~/b cat .java-version
11.0
⋊> ~/b cd ..
⋊> ~ cd a/
⋊> ~/a cat .java-version
1.8
⋊> ~/a mkdir b
⋊> ~/a cd b
⋊> ~/a/b java -version
java version "1.8.0_192"
Java(TM) SE Runtime Environment (build 1.8.0_192-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.192-b12, mixed mode)
⋊> ~/a/b jenv local 11.0
⋊> ~/a/b java -version
openjdk version "11.0.1" 2018-10-16
OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)

ディレクトリごとに使用バージョンが .java-version に書き込まれ、自分のディレクトリにない場合は親のものを見に行く、みたいな感じですね。.gitignore.java-version を追加してあげるのがよさそう。

まとめ

まとめることなどない。
Qiita 最悪記事ランキングにランクインできそうな記事になりました。
間違って無駄に個人情報とか公開してないか心配。