Help us understand the problem. What is going on with this article?

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

参考文献

dwango
Born in the net, Connected by the net.
https://dwango.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした