I've been using Java on OS X for many, many years and recently when Apple stopped including Java by default I let the OS go and install it for me (Apple's variety, of course).
我已经在OS X上使用Java很多年了,最近苹果公司在默认情况下停止使用Java时我会让操作系统为我安装它(Apple当然是多种多样的)。
So now I'm using OS X 10.8 and I need to install Java 7 so I just got Oracle's Update 15 in DMG form and ran the installer. It updated my /usr/bin/java (and related files) to point here:
所以现在我正在使用OS X 10.8,我需要安装Java 7,所以我只是以DMG格式获得了Oracle的Update 15并运行了安装程序。它更新了我的/ usr / bin / java(及相关文件)以指向:
/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java
Tracing this back to '/System/Library/Frameworks/JavaVM.framework/Versions' everything either points to 'Current' or 'CurrentJDK', the former being a link to 'A' (which is Oracle's Java 7, from what I can tell, not sure why it is 'A') and the latter being a link to Apple's Java 6 in '/System/Library/Java/JavaVirtualMachines/1.6.0.jdk'.
将其追溯到'/System/Library/Frameworks/JavaVM.framework/Versions',所有内容都指向'Current'或'CurrentJDK',前者是指向'A'的链接(这是Oracle的Java 7,我可以告诉,不知道为什么它是'A')而后者是'/System/Library/Java/JavaVirtualMachines/1.6.0.jdk'中Apple的Java 6的链接。
Now this is all really confusing but this isn't even my question yet. It appears there is a Java 7 installed here:
现在这一切都让人感到困惑,但这还不是我的问题。看来这里安装了一个Java 7:
/System/Library/Frameworks/JavaVM.framework/Versions/A
But there is also a Java 7 installed here:
但是这里还安装了Java 7:
/Library/Java/JavaVirtualMachines/jdk1.7.0_15.jdk
Finding 'java' in both and printing out the version yields the same version and build (java version "1.7.0_15"), however, when hashing the files they are different.
在两者中查找'java'并打印出版本会产生相同的版本和构建(java版本“1.7.0_15”),但是,当对文件进行散列时它们是不同的。
So does this mean Oracle installed Java 7 in two different places? If so, why? Which am I supposed to use? And why do some things still point to Java 6 (CurrentJDK).
那么这是否意味着Oracle在两个不同的地方安装了Java 7?如果是这样,为什么?我应该使用哪个?为什么有些东西仍然指向Java 6(CurrentJDK)。
I've looked on Oracle's website but nothing there clears anything up.
我查看了甲骨文的网站,但没有任何内容可以解决。
3 个解决方案
#1
60
Oracle's JVM is only installed in one location. You've been misled!
Oracle的JVM仅安装在一个位置。你被误导了!
As you've noted, the Java commands in /usr/bin
are symlinks to binaries in /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands
. The binaries within that directory are stub applications that determine which Java VM to use*, and then exec the corresponding real binary within that VM version. This is why all of the binaries within /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands
are almost identical in size, despite the fact that you'd expect them to be implementing quite different functionality.
如您所知,/ usr / bin中的Java命令是/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands中二进制文件的符号链接。该目录中的二进制文件是存根应用程序,它们确定要使用哪个Java VM *,然后在该VM版本中执行相应的实际二进制文件。这就是为什么/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands中的所有二进制文件的大小几乎相同的原因,尽管您希望它们实现完全不同的功能。
You can see this in action by using dtrace
:
您可以使用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
The given dtrace
invocation prints out the path argument to posix_spawn
when it is called by java -version
. In my case the stub application has found Apple's Java 1.6 runtime in /System/Library/Java/JavaVirtualMachines/1.6.0.jdk
and is invoking that version of the java
command.
给定的dtrace调用在java -version调用时打印出posix_spawn的path参数。在我的例子中,存根应用程序在/System/Library/Java/JavaVirtualMachines/1.6.0.jdk中找到了Apple的Java 1.6运行时,并且正在调用该版本的java命令。
The stub binaries also have another benefit: when they detect that no Java VM is installed they will prompt the user to install one.
存根二进制文件还有另一个好处:当它们检测到没有安装Java VM时,它们将提示用户安装一个。
As for the CurrentJDK
symlink, as best as I can tell this for sake of backwards-compatibility with the past when Apple was the only source of the JVM on OS X.
至于CurrentJDK符号链接,最好的我可以告诉它为了向后兼容过去,当Apple是OS X上JVM的唯一来源时。
* A combination of factors are considered when determining which Java VM should be used. JAVA_HOME
is used if set (try JAVA_HOME=/tmp java
). If JAVA_HOME
is not set then the list of all virtual machines on the system is discovered. The JAVA_VERSION
and JAVA_ARCH
environment variables are used, if set, to filter the list of virtual machines to a particular version and supported architecture. The resulting list is then sorted by architecture (preferring 64-bit over 32-bit) and version (newer is better), and the best match is returned.
*在确定应使用哪个Java VM时,会考虑多种因素的组合。如果设置了JAVA_HOME(尝试JAVA_HOME = / tmp java)。如果未设置JAVA_HOME,则会发现系统上所有虚拟机的列表。如果设置了JAVA_VERSION和JAVA_ARCH环境变量,则将虚拟机列表过滤为特定版本和支持的体系结构。然后根据体系结构(优选64位超过32位)和版本(更新更好)对结果列表进行排序,并返回最佳匹配。
#2
9
The Oracle Java 7 JRE (i.e. the one that is used by the web browser plugin to run applets and Java Web Start) installs itself in /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home
, and it is this one that any automatic updates will affect. The JDK (the one you download from http://www.oracle.com/technetwork/java/javase/downloads/index.html) installs by creating a directory under /Library/Java/JavaVirtualMachines
, and it's up to you to update this yourself. You can have multiple JDK versions installed side by side but only one "public" JRE under JavaAppletPlugin.plugin
(which will correspond to the latest installed JDK or a later version if it has been auto-updated since).
Oracle Java 7 JRE(即Web浏览器插件用于运行applet和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或更新版本,如果它已经自动更新)。
As explained by bdash, the commands under /usr/bin
are stubs that delegate to whichever JDK/JRE is pointed to by the JAVA_HOME
environment variable, or if that is not set then they will pick the most appropriate Java to run. You can use /usr/libexec/java_home
to see which one the stubs would pick. If no Java is installed the stubs will offer to install the latest Apple Java 6 (as far as I know they will not offer to install Java 7).
正如bdash所解释的那样,/ usr / bin下的命令是委托给JAVA_HOME环境变量指向的JDK / JRE的存根,或者如果没有设置,那么它们将选择最合适的Java来运行。您可以使用/ usr / libexec / java_home来查看存根将选择哪一个。如果没有安装Java,那么存根将提供安装最新的Apple Java 6(据我所知他们不会提供安装Java 7)。
#3
3
I find this post: https://developer.apple.com/library/mac/qa/qa1170/_index.html The /usr/libexec/java_home tool dynamically finds the top Java version specified in Java Preferences for the current user.
我发现这篇文章:https://developer.apple.com/library/mac/qa/qa1170/_index.html / usr / libexec / java_home工具动态查找当前用户在Java Preferences中指定的*Java版本。
#1
60
Oracle's JVM is only installed in one location. You've been misled!
Oracle的JVM仅安装在一个位置。你被误导了!
As you've noted, the Java commands in /usr/bin
are symlinks to binaries in /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands
. The binaries within that directory are stub applications that determine which Java VM to use*, and then exec the corresponding real binary within that VM version. This is why all of the binaries within /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands
are almost identical in size, despite the fact that you'd expect them to be implementing quite different functionality.
如您所知,/ usr / bin中的Java命令是/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands中二进制文件的符号链接。该目录中的二进制文件是存根应用程序,它们确定要使用哪个Java VM *,然后在该VM版本中执行相应的实际二进制文件。这就是为什么/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands中的所有二进制文件的大小几乎相同的原因,尽管您希望它们实现完全不同的功能。
You can see this in action by using dtrace
:
您可以使用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
The given dtrace
invocation prints out the path argument to posix_spawn
when it is called by java -version
. In my case the stub application has found Apple's Java 1.6 runtime in /System/Library/Java/JavaVirtualMachines/1.6.0.jdk
and is invoking that version of the java
command.
给定的dtrace调用在java -version调用时打印出posix_spawn的path参数。在我的例子中,存根应用程序在/System/Library/Java/JavaVirtualMachines/1.6.0.jdk中找到了Apple的Java 1.6运行时,并且正在调用该版本的java命令。
The stub binaries also have another benefit: when they detect that no Java VM is installed they will prompt the user to install one.
存根二进制文件还有另一个好处:当它们检测到没有安装Java VM时,它们将提示用户安装一个。
As for the CurrentJDK
symlink, as best as I can tell this for sake of backwards-compatibility with the past when Apple was the only source of the JVM on OS X.
至于CurrentJDK符号链接,最好的我可以告诉它为了向后兼容过去,当Apple是OS X上JVM的唯一来源时。
* A combination of factors are considered when determining which Java VM should be used. JAVA_HOME
is used if set (try JAVA_HOME=/tmp java
). If JAVA_HOME
is not set then the list of all virtual machines on the system is discovered. The JAVA_VERSION
and JAVA_ARCH
environment variables are used, if set, to filter the list of virtual machines to a particular version and supported architecture. The resulting list is then sorted by architecture (preferring 64-bit over 32-bit) and version (newer is better), and the best match is returned.
*在确定应使用哪个Java VM时,会考虑多种因素的组合。如果设置了JAVA_HOME(尝试JAVA_HOME = / tmp java)。如果未设置JAVA_HOME,则会发现系统上所有虚拟机的列表。如果设置了JAVA_VERSION和JAVA_ARCH环境变量,则将虚拟机列表过滤为特定版本和支持的体系结构。然后根据体系结构(优选64位超过32位)和版本(更新更好)对结果列表进行排序,并返回最佳匹配。
#2
9
The Oracle Java 7 JRE (i.e. the one that is used by the web browser plugin to run applets and Java Web Start) installs itself in /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home
, and it is this one that any automatic updates will affect. The JDK (the one you download from http://www.oracle.com/technetwork/java/javase/downloads/index.html) installs by creating a directory under /Library/Java/JavaVirtualMachines
, and it's up to you to update this yourself. You can have multiple JDK versions installed side by side but only one "public" JRE under JavaAppletPlugin.plugin
(which will correspond to the latest installed JDK or a later version if it has been auto-updated since).
Oracle Java 7 JRE(即Web浏览器插件用于运行applet和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或更新版本,如果它已经自动更新)。
As explained by bdash, the commands under /usr/bin
are stubs that delegate to whichever JDK/JRE is pointed to by the JAVA_HOME
environment variable, or if that is not set then they will pick the most appropriate Java to run. You can use /usr/libexec/java_home
to see which one the stubs would pick. If no Java is installed the stubs will offer to install the latest Apple Java 6 (as far as I know they will not offer to install Java 7).
正如bdash所解释的那样,/ usr / bin下的命令是委托给JAVA_HOME环境变量指向的JDK / JRE的存根,或者如果没有设置,那么它们将选择最合适的Java来运行。您可以使用/ usr / libexec / java_home来查看存根将选择哪一个。如果没有安装Java,那么存根将提供安装最新的Apple Java 6(据我所知他们不会提供安装Java 7)。
#3
3
I find this post: https://developer.apple.com/library/mac/qa/qa1170/_index.html The /usr/libexec/java_home tool dynamically finds the top Java version specified in Java Preferences for the current user.
我发现这篇文章:https://developer.apple.com/library/mac/qa/qa1170/_index.html / usr / libexec / java_home工具动态查找当前用户在Java Preferences中指定的*Java版本。