謎なMacのJavaインストール構成
先日、ようやくMac版JDK7のGA版が登場しました。今までMacのJDKはAppleが提供していましたが、7からはOracleからの提供となります。
早速インストールしたのですが、実に奇妙な現象が見られたのでここに記録しておきます。
インストールはOracleのダウンロードサイトからダウンロードしたインストーラを使ってインストールします。特に難しいことはなく、指示に従ってインストールするだけです。
インストール後、JDK7をデフォルトのJDKにするには設定変更が必要です。ここで説明されているのですが、/Applications/Utilities/Java Preferences.app を起動し、以下のスクリーンショットのように [Java SE7] をドラッグして一番上に持って行きます。
これでJDK7がデフォルトで有効になるはず、なのですが自分の環境ではそうなりませんでした...。
$ java -version java version "1.6.0_31" Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-11M3635) Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-415, mixed mode)
その時は一旦あきらめたのですが、後日、ふと .bash_profile に環境変数 JAVA_HOME を設定しており、そこで JDK6 のインストールパスを指定していたことを思い出しました。そこで、JAVA_HOME の設定を削除して、シェルを再度開いて確認してみると...
$ java -version java version "1.7.0_04" Java(TM) SE Runtime Environment (build 1.7.0_04-b21) Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)
ちゃんとJDK7を認識しています! これで晴れて自分のMac環境もJDK7環境になりました。
しかし疑問が残ります。JAVA_HOME は設定していましたが、パスはそこには通していませんでした。実際、環境変数を変更した前後で "which java" をしても /usr/bin/java を指しています。
まず、/usr/bin/java の実体を調べてみます。
$ ls -li /usr/bin/java 40738383 lrwxr-xr-x 1 root wheel 74 4 15 20:59 /usr/bin/java -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java
/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java にシンボリックリンクが貼られています。
で、パスの途中に出てくる "Current" というディレクトリですが、以下のように "A" というディレクトリに対するシンボリックリンクとなっています。
$ ls -li total 64 40738298 lrwxr-xr-x 1 root wheel 10 4 15 20:59 1.4 -> CurrentJDK 40738299 lrwxr-xr-x 1 root wheel 10 4 15 20:59 1.4.2 -> CurrentJDK 40738300 lrwxr-xr-x 1 root wheel 10 4 15 20:59 1.5 -> CurrentJDK 40738301 lrwxr-xr-x 1 root wheel 10 4 15 20:59 1.5.0 -> CurrentJDK 40738302 lrwxr-xr-x 1 root wheel 10 4 15 20:59 1.6 -> CurrentJDK 40738303 lrwxr-xr-x 1 root wheel 10 4 15 20:59 1.6.0 -> CurrentJDK 24547503 drwxr-xr-x 8 root wheel 272 4 15 21:56 A 40739474 lrwxr-xr-x 1 root wheel 1 4 15 20:59 Current -> A 40738356 lrwxr-xr-x 1 root wheel 59 4 15 20:59 CurrentJDK -> /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents
この A という名前のディレクトリですが、Mac上にフレームワーク環境を構築する際には、複数のバージョンを入れておきたい場合は、A, B, C... というアルファベット順のディレクトリを作って、そこに異なるバージョンを入れるようにするという慣習になっているようです (Appleの解説はここ) 。
で、A/Commands の中を覗いてみると次のようになっていました。
$ ls -li A/Commands total 1280 40738305 -rwxr-xr-x 1 root wheel 54272 4 15 20:59 appletviewer 40738306 -rwxr-xr-x 1 root wheel 54272 4 15 20:59 apt 40738307 -rwxr-xr-x 1 root wheel 54272 4 15 20:59 extcheck 40738308 -rwxr-xr-x 1 root wheel 54272 4 15 20:59 idlj 40738309 -rwxr-xr-x 1 root wheel 54272 4 15 20:59 jar 40738310 -rwxr-xr-x 1 root wheel 54272 4 15 20:59 jarsigner 40738311 -rwxr-xr-x 1 root wheel 54272 4 15 20:59 java 40738312 -rwxr-xr-x 1 root wheel 67456 4 15 20:59 java_home ...
リンクではなく、実ファイルのようです。もしかしてハードリンクなのかな?と思ったのですが、JDK7のコマンドディレクトリに入っている java を確認してみると...
$ ls -li /Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home/bin total 6888 41515326 -rwxrwxr-x 1 root wheel 88864 4 20 14:58 appletviewer 41515327 -rwxrwxr-x 1 root wheel 88864 4 20 14:58 apt 41515328 -rwxrwxr-x 1 root wheel 88864 4 20 14:58 extcheck 41515329 -rwxrwxr-x 1 root wheel 88864 4 20 14:58 idlj 41515330 -rwxrwxr-x 1 root wheel 88864 4 20 14:58 jar 41515331 -rwxrwxr-x 1 root wheel 88864 4 20 14:58 jarsigner 41515332 -rwxrwxr-x 1 root wheel 88800 4 20 14:58 java 41515333 -rwxrwxr-x 1 root wheel 88864 4 20 14:58 javac ...
実体が違うようですし、何よりファイルサイズもタイムスタンプも異なります! JDK7の同名ファイルより古いですし。
そして、環境変数 JAVA_HOME の設定を戻して、JDK6を指すようにしてから、A/Commands の下を見てみると...
$ java -version java version "1.6.0_31" Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-11M3635) Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-415, mixed mode) $ which java /usr/bin/java $ ls -li /System/Library/Frameworks/JavaVM.framework/Versions/A/Commands total 1280 ... 40738311 -rwxr-xr-x 1 root wheel 54272 4 15 20:59 java ...
全く変わっていないんですけど...。
ということは、これは推測なのですが /System/Library/Frameworks/JavaVM.framework/Versions/Commands 以下に入っているコマンドは全てプロキシで、呼び出されたら現在のデフォルトバージョンとして指定されているJavaのディレクトリにある同名のコマンドを呼ぶようになっているということでしょうか?
で、その呼び出し先を指定するのが Java Preferences.app の設定であり、環境変数 JAVA_HOME が設定されている場合はさらにそれを優先させる...と言った所ですかねえ。
以下のAppleの開発者向けドキュメントを読んでみたのですがイマイチ要領を得ません。
http://developer.apple.com/library/mac/#qa/qa1170/_index.html
http://developer.apple.com/library/mac/#documentation/Java/Conceptual/Java14Development/00-Intro/JavaDevelopment.html
どなたかこのあたりの事情に詳しい人いますか?