49

我在 OS X 上使用 Java 已经很多很多年了,最近当 Apple 停止默认包含 Java 时,我让操作系统去为我安装它(当然是 Apple 的品种)。

所以现在我使用的是 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”,所有内容都指向“Current”或“CurrentJDK”,前者是指向“A”的链接(据我所知,这是 Oracle 的 Java 7告诉,不知道为什么它是'A'),后者是'/System/Library/Java/JavaVirtualMachines/1.6.0.jdk'中Apple Java 6的链接。

现在这一切都非常令人困惑,但这甚至还不是我的问题。这里似乎安装了 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)。

我查看了甲骨文的网站,但没有任何东西可以清除。

4

3 回答 3

79

Oracle 的 JVM 只安装在一个位置。你被误导了!

正如您所指出的,Java 命令中/usr/bin的符号链接到/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands. 该目录中的二进制文件是存根应用程序,用于确定要使用的 Java VM*,然后在该 VM 版本中执行相应的实际二进制文件。这就是为什么其中的所有二进制文件/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands大小几乎相同的原因,尽管您希望它们实现完全不同的功能。

您可以使用以下命令查看此操作dtrace

mrowe@angara:~$ 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调用打印出 path 参数,posix_spawn当它被 调用时java -version。在我的例子中,存根应用程序在其中找到了 Apple 的 Java 1.6 运行时/System/Library/Java/JavaVirtualMachines/1.6.0.jdk并正在调用该版本的java命令。

存根二进制文件还有另一个好处:当它们检测到没有安装 Java VM 时,它们会提示用户安装一个。

至于CurrentJDK符号链接,为了与过去苹果是 OS X 上 JVM 的唯一来源时向后兼容,尽我所能告诉这一点。


* 在确定应使用哪个 Java VM 时,综合考虑了多种因素。JAVA_HOME如果设置(尝试JAVA_HOME=/tmp java)则使用。如果JAVA_HOME未设置,则会发现系统上所有虚拟机的列表。JAVA_VERSION和环境变量(JAVA_ARCH如果设置)用于将虚拟机列表过滤到特定版本和支持的体系结构。然后根据体系结构(优先于 64 位而不是 32 位)和版本(更新更好)对结果列表进行排序,并返回最佳匹配。

于 2013-02-28T10:40:08.647 回答
11

Oracle Java 7 JRE(即,Web 浏览器插件用来运行小程序和 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 版本,但只能在一个“公共”JRE 下JavaAppletPlugin.plugin安装(这将对应于最新安装的 JDK 或以后自动更新的版本)。

正如 bdash 所解释的,下面的命令/usr/bin是委托给环境变量指向的任何 JDK/JRE 的存根JAVA_HOME,或者如果没有设置,那么它们将选择最合适的 Java 来运行。您可以使用/usr/libexec/java_home来查看存根会选择哪一个。如果没有安装 Java,存根将提供安装最新的 Apple Java 6(据我所知,他们不会提供安装 Java 7)。

于 2013-02-28T11:08:03.293 回答
5

我找到了这篇文章: https ://developer.apple.com/library/mac/qa/qa1170/_index.html /usr/libexec/java_home 工具动态查找在 Java 首选项中为当前用户指定的最高 Java 版本。

于 2015-05-18T09:51:02.307 回答