Edited at

OSXでJavaのバージョンを切り替える

More than 1 year has passed since last update.


忙しい人のための

設定ファイルに記述する.

.profile, .bashrc, .zshrcなどなんでもいいですが,環境変数JAVA_HOMEjava_homeコマンドを使って設定します.

export JAVA_HOME=$(/System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java_home -v "1.6")

PATH=${JAVA_HOME}/bin:${PATH}

以下詳細.


はじめに

先日,Java8で遊んでみようと思って,OSX(10.7)にインストールしました.

java -versionを打つと

java version "1.8.0-ea"

Java(TM) SE Runtime Environment (build 1.8.0-ea-b121)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b63, mixed mode)

がでて,ちゃんと1.8になってるなよしよし.


と思って生活してたんだけども,思わぬところで事故ったので,1.6に戻す事にしました.

でも,いじっているうちに良くわからなくなったので,ログとしてやったことをまとめておこうと思います.


Javaのバージョンを切り替える2つの方法

OSXでJavaのバージョンを切り替える方法は2つ(しか知らない)あります.



  1. JAVA_HOMEを切り替える


  2. 非推奨: /System/Library/Frameworks/JavaVM.framework/Versionsの下のCurrentJDKを切り替える


javaコマンドの実体

まず,1.8をインストールした後,which javaを打つと,/usr/bin/javaが返ってきます.

実は,シンボリックリンクなのでls -l /usr/bin/javaでリンク先を見てみると,

java -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java

という結果が返ってきます.

javaコマンドだけではなく,javacなどのコマンドも/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands下にあるものを指してます.


MacOSXにおけるjavaのバージョンについて

Mac OSXのJavaのバージョンは一応/System/Library/Frameworks/JavaVM.framework/Versionsで管理(?)されています(本当か?).

ここの,ディレクトリをみてみると,

$ ls -l /System/Library/Frameworks/JavaVM.framework/Versions

total 40K
lrwxr-xr-x 1 root wheel 10 8 27 12:53 1.4 -> CurrentJDK/
lrwxr-xr-x 1 root wheel 10 8 27 12:53 1.4.2 -> CurrentJDK/
lrwxr-xr-x 1 root wheel 10 8 27 12:53 1.5 -> CurrentJDK/
lrwxr-xr-x 1 root wheel 10 8 27 12:53 1.5.0 -> CurrentJDK/
lrwxr-xr-x 1 root wheel 10 8 27 12:53 1.6 -> CurrentJDK/
lrwxr-xr-x 1 root wheel 10 8 27 12:53 1.6.0 -> CurrentJDK/
drwxr-xr-x 9 root wheel 306 1 27 18:57 A/
lrwxr-xr-x 1 root wheel 1 1 28 12:39 Current -> A/
lrwxr-xr-x 1 root wheel 59 8 27 12:53 CurrentJDK -> /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/

となっています.

ん?1.4も1.5も1.6もCurrentJDKを指してます.

CurrentJDKは,/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/を指しています.

つまり,バージョン1.4も1.5も,実は1.6だったということ.


各Javaバージョンの実体

OSXへJavaを提供する提供元は2箇所あります.AppleとOracleです.

Appleが提供しているJavaは,CurrentJDKの指している/System/Library/Java/JavaVirtualMachinesに格納されています.

また,Oracleが提供しているパッケージを使って1.7や1.8をインストールした場合は,

/Library/Java/JavaVirtualMachinesになります.

JDKの置き場所は2箇所ある.


JDKのバージョン切り替え


1. JAVA_HOMEを切り替える

OSXのJavaは次のような項目で環境が決定されるそうです.


  1. Java Preferencesの優先順位をみて決定する

  2. 環境変数にJAVA_HOMEが設定してある場合はこちらを優先する

Java Preferencesは,2012年10月16日にのJavaのセキュリティアップデート(Java for OS X 2012-006)で削除されました.

これ以降(?),OSXにJavaに提供するのはAppleからOracleに変わったようです.

どちらにせよ,JAVA_HOMEを設定して上書きしてしまえばバージョンは変更できそうです.

このバージョンのパスを返す便利なコマンドが実は存在します.


java_home コマンド

このコマンドは,指定したJavaバージョンのhomeがどこにあるかを返すコマンドです.

配置されている場所は,/System/Library/Frameworks/JavaVM.framework/Versions/A/Commandsです.

実行するとこんな感じになります.

$ ./java_home -v "1.4"

Unable to find any JVMs matching version "1.4".
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home
$ ./java_home -v "1.5"
Unable to find any JVMs matching version "1.5".
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home
$ ./java_home -v "1.6"
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
$ ./java_home -v "1.7"
Unable to find any JVMs matching version "1.7".
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home
$ ./java_home -v "1.8"
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home

1.6と1.8しかインストールしてないので,1.4,1.5と1.7は最新である1.8を指します.

1.6だけはインストールされているので,ちゃんと1.6のパスが返ってきます.


設定ファイルに記述する

.profile, .bashrc, .zshrcなどなんでもいいですが,どれかで,環境変数JAVA_HOMEに設定します.

さきほどのjava_homeコマンドを使います.

export JAVA_HOME=`/System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java_home -v "1.6"`

PATH=${JAVA_HOME}/bin:${PATH}

以降,1.6の部分を,1.8に変えると簡単にバージョンを切り替えることができます.



2. 非推奨?: /System/Library/Frameworks/JavaVM.framework/Versionsの下のCurrentJDKを切り替える

この方法は,OSX標準の構造を色々といじるので,いつ,どこで,どんな事件が起こるかわかりません.

そのため,個人的には非推奨です.

アンチパターン?として,一応紹介しておきます.

まず,/System/Library/Frameworks/JavaVM.framework/Versionsにある,1.6以前のバージョンを整理します.

1.4 -> CurrentJDK/

1.4.2 -> CurrentJDK/
1.5 -> CurrentJDK/
1.5.0 -> CurrentJDK/
1.6 -> CurrentJDK/
1.6.0 -> CurrentJDK/
CurrentJDK -> /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/

CurrentJDKをバシバシ切り替えたいので,1.4と1.5の向き先を1.6にします.

(上書きしようと思ったけれども,-f,Fつけても上書きされなかった..)

sudo rm 1.4;   sudo ln -sf 1.4.2 1.4

sudo rm 1.4.2; sudo ln -sf 1.5 1.4.2
sudo rm 1.5; sudo ln -s 1.5.0 1.5
sudo rm 1.5.0; sudo ln -s 1.6 1.5.0
sudo rm 1.6; sudo ln -s 1.6.0 1.6
sudo rm 1.6.0; sudo ln -s /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents 1.6.0
sudo rm CurrentJDK; sudo ln -s 1.6 CurrentJDK

次に,1.8を入れたので1.8用のリンクを追加します.

ln -s /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents 1.8.0

ln -s 1.8.0 1.8

すると,こういう構成になります.

$ ls -l

total 40K
lrwxr-xr-x 1 root wheel 5 1 28 16:39 1.4 -> 1.4.2/
lrwxr-xr-x 1 root wheel 3 1 28 16:40 1.4.2 -> 1.5/
lrwxr-xr-x 1 root wheel 5 1 28 16:45 1.5 -> 1.5.0/
lrwxr-xr-x 1 root wheel 3 1 28 16:45 1.5.0 -> 1.6/
lrwxr-xr-x 1 root wheel 5 1 28 16:46 1.6 -> 1.6.0/
lrwxr-xr-x 1 root wheel 59 1 28 16:47 1.6.0 -> /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/
lrwxr-xr-x 1 root wheel 5 1 28 15:27 1.8 -> 1.8.0/
lrwxr-xr-x 1 root wheel 55 1 28 15:26 1.8.0 -> /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/
drwxr-xr-x 9 root wheel 306 1 27 18:57 A/
lrwxr-xr-x 1 root wheel 1 1 28 12:39 Current -> A/
lrwxr-xr-x 1 root wheel 3 1 28 16:50 CurrentJDK -> 1.6/

CurrentJDKの向き先を1.8や1.6にすると切り替えられるようになりました.


javaコマンド

この状態でjava -versionコマンドを実行すると,まだ1.8のjavaが実行されてます.

Current -> A下のCommand下にあるjavaコマンドを実行しています(Aってなんだ...).

Aの中身は,

$ ls -l A

total 40K
lrwxr-xr-x 1 root wheel 3 1 27 18:57 1.6 -> 1.6
drwxr-xr-x 44 root wheel 1.5K 8 27 12:53 Commands/
drwxr-xr-x 4 root wheel 136 11 18 2011 Frameworks/
drwxr-xr-x 14 root wheel 476 3 29 2013 Headers/
-rwxr-xr-x 1 root wheel 102K 8 27 12:53 JavaVM*
drwxr-xr-x 42 root wheel 1.4K 8 27 12:53 Resources/
drwxr-xr-x 3 root wheel 102 8 27 12:53 _CodeSignature/

のようになっています.

1.6のシンボリックリンクは無限ループになってます.

おそらく,1.8をインストールすると,

/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/binにあるコマンドが,

/System/Library/Frameworks/JavaVM.framework/Versions/A/Commandsにコピーされているような気がします.

なので,これもシンボリックリンクで参照してあげます.

sudo mv Commands Commands.back

sudo ln -s /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/bin Commands


参考文献