2013-02-27 41 views
33

我已經在OS X上使用Java很多很多年了,最近當Apple在默認情況下停止包括Java時,我讓操作系統去安裝它(當然是蘋果的多種產品)。瞭解甲骨文的Java在Mac上

所以現在我使用的是OS X 10.8,我需要安裝Java 7,所以我剛剛獲得DMG格式的Oracle更新15並運行安裝程序。它更新了我的/ usr/bin中/ JAVA(和相關文件)在這裏指出:

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

跟蹤這回「/System/Library/Frameworks/JavaVM.framework/Versions」一切要麼指向「當前」或'CurrentJDK',前者是'A'(這是Oracle的Java 7,根據我可以說的,不知道爲什麼是'A')的鏈接,後者是'/ System中Apple的Java 6的鏈接/Library/Java/JavaVirtualMachines/1.6.0.jdk」。

現在這一切都很混亂,但這甚至不是我的問題。這似乎在這裏安裝了Java 7:

/System/Library/Frameworks/JavaVM.framework/Versions/A 

但也有在這裏安裝了Java 7:

/Library/Java/JavaVirtualMachines/jdk1.7.0_15.jdk 

查找「Java」作爲兩個和印刷出來的版本產生了相同的版本和構建(java版本「1.7.0_15」),但是,當他們是不同的文件散列。

那麼這是否意味着Oracle在兩個不同的地方安裝了Java 7?如果是這樣,爲什麼?我應該用哪個?爲什麼有些東西仍然指向Java 6(CurrentJDK)。

我查看過Oracle的網站,但沒有任何東西可以清除任何東西。

+0

問完全一樣的問題,我想。我真的很困惑我的Mac中的「2」JRE。您的描述清晰,乾淨。感謝您提問:) – 2016-11-11 23:11:14

回答

56

Oracle的JVM只安裝在一個位置。你被誤導了!

正如您所指出的,/usr/bin中的Java命令是/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands中的二進制文件的符號鏈接。該目錄中的二進制文件是存根應用程序,用於確定要使用哪個Java VM *,然後在該VM版本中執行相應的真實二進制文件。這就是爲什麼/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands中的所有二進制文件的大小几乎相同的原因,儘管您期望它們實現的功能完全不同。

您可以通過使用dtrace在行動中看到這一點:

[email protected]:~$ sudo dtrace -n 'syscall::posix_spawn:entry { trace(copyinstr(arg1)); }' -c "/usr/bin/java -version" 
dtrace: description 'syscall::posix_spawn:entry ' matched 1 probe 
dtrace: pid 44727 has exited 
CPU  ID     FUNCTION:NAME 
    8 619    posix_spawn:entry /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java 

給出的dtrace調用打印出的路徑參數posix_spawn當它被稱爲java -version。在我的案例中,存根應用程序在/System/Library/Java/JavaVirtualMachines/1.6.0.jdk中找到了Apple的Java 1.6運行庫,並調用該版本的java命令。

存根二進制文件還有另一個好處:當它們檢測到沒有安裝Java VM時,它們將提示用戶安裝一個。

對於CurrentJDK符號鏈接,作爲最好的,我可以告訴這與過去的向後兼容的緣故,當蘋果公司的JVM在OS X


的唯一來源*的組合確定應使用哪個Java VM時考慮因素。如果已設置,則使用JAVA_HOME(嘗試JAVA_HOME=/tmp java)。如果未設置JAVA_HOME,則會發現系統上所有虛擬機的列表。如果設置,則使用JAVA_VERSIONJAVA_ARCH環境變量將虛擬機列表篩選爲特定版本和支持的體系結構。然後根據體系結構(最好是32位的64位)和版本(更新的更好)對結果列表進行排序,並返回最佳匹配。

+1

非常感謝您,我甚至沒有考慮過查看文件的大小。我可以自己調查一下,但是你在哪裏說「確定要使用哪個Java虛擬機的存根應用程序」......他們如何做出這樣的決定?希望它與JAVA_HOME一起,但也許還有其他的東西? – rjcarr 2013-02-28 17:45:05

+1

考慮因素的組合。如果設置了JAVA_HOME(嘗試'JAVA_HOME =/tmp java')。如果未設置JAVA_HOME,則會發現系統上所有虛擬機的列表。如果設置,則使用JAVA_VERSION和JAVA_ARCH環境變量將虛擬機列表篩選爲特定版本和受支持的體系結構。然後根據體系結構(最好是32位的64位)和版本(更新的更好)對結果列表進行排序,並返回最佳匹配。 – bdash 2013-02-28 20:43:20

8

甲骨文的Java 7 JRE(即所使用的網絡瀏覽器插件運行小程序和Java Web Start的)安裝本身/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home,而正是這一個,任何自動更新將影響。 JDK(您從http://www.oracle.com/technetwork/java/javase/downloads/index.html下載的那個)通過在/Library/Java/JavaVirtualMachines下創建一個目錄進行安裝,並且由您自己來更新。您可以並排安裝多個JDK版本,但只有一個在JavaAppletPlugin.plugin下的「公共」JRE(如果自此之後已自動更新,它將對應於最新安裝的JDK或更高版本)。

正如bdash解釋,/usr/bin下的命令是存根由JAVA_HOME環境變量取其JDK/JRE指向該委託,或者如果未設置,那麼他們會選擇最合適的Java運行。您可以使用/usr/libexec/java_home來查看存根將選擇哪一個。如果安裝Java,存根將提供安裝最新的Apple Java 6(據我所知他們將而不是提供安裝Java 7)。

+0

感謝您的解釋,這是有道理的。我將不得不測試JAVA_HOME var和java_home bin以確保能夠按預期工作。 – rjcarr 2013-02-28 17:47:01

+0

@rjcarr我意識到我的答案並不完全清楚 - 存根將始終尊重JAVA_HOME - 運行'/ usr/libexec/java_home'會顯示如果JAVA_HOME未被設置,它將選擇哪一個。 – 2013-02-28 19:11:18

+1

@bdash和伊恩真的很感激你的答案。由於不同的原因,我到達這個帖子,我設法通過弄亂/誤解各種符號鏈接和存根來搞砸我的Java安裝。如果其他人遇到這個問題,我在運行ant時出錯:「java.lang.NoClassDefFoundError:無法初始化sun.util.calendar.ZoneInfoFile類,在sun.util.calendar.ZoneInfo.getTimeZone(ZoneInfo.java:663)」和「之前有一個錯誤:java.lang.AssertionError:無法在sun.nio.fs.DefaultFileSystemProvider.create(DefaultFileSystemProvider.java:73)中識別的平臺」 - Phew! – 2013-08-22 05:04:50