忙しい人のための
設定ファイルに記述する.
.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}
以下詳細.
はじめに
先日,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つ(しか知らない)あります.
-
JAVA_HOME
を切り替える -
非推奨:
/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は次のような項目で環境が決定されるそうです.
- Java Preferencesの優先順位をみて決定する
- 環境変数に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