Mac OSX Java终端版本不正确

63
当我从Oracle的网站安装Java 7时,虽然偏好设置菜单更新了并在双击.jar文件时正确地执行它们,但终端窗口的版本仍为1.6.0_43,并且从终端运行相同的.jar文件会因旧版本而导致运行时错误。当我导航到/Library/Java/JavaVirtualMachines/时,我看到一个空文件夹。根据我在其他文章中看到的内容,这里应该是Java 1.7.0版本文件夹所在的位置。请问发生了什么?如何使终端使用正确的Java版本?
total 64
lrwxr-xr-x  1 root  wheel   10 Mar 17 21:38 1.4 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 Mar 17 21:38 1.4.2 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 Mar 17 21:38 1.5 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 Mar 17 21:38 1.5.0 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 Mar 17 21:38 1.6 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 Mar 17 21:38 1.6.0 -> CurrentJDK
drwxr-xr-x  8 root  wheel  272 Mar 17 21:38 A
lrwxr-xr-x  1 root  wheel    1 Mar 17 21:38 Current -> A
lrwxr-xr-x  1 root  wheel   59 Mar 17 21:38 CurrentJDK -> /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents

(2)

ls -ld /usr/bin/java
lrwxr-xr-x  1 root  wheel  74 Mar 17 21:38 /usr/bin/java -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java

编辑:对于新答案的错误表示抱歉,太习惯了一些长时间后阻止原帖编辑的网站...


3
目前在Mac OSX上进行Java集成是一团糟,因为苹果已经停止了官方支持,Oracle也不太知道或者关心如何正确地集成。如果你在/Library/Java/JavaVirtualMachines中找不到Java 7,则请查看/System/Library/Frameworks/JavaVM.framework/Versions。它应该在那里,作为一个独立的目录或链接到“Current”。 - Perception
1
很简单 - Apple的代码和只有Apple的代码在/System目录下,而第三方库则在/Library目录下供所有用户使用。 - mmmmmm
@DGolberg - 你安装的是哪个具体的Java版本?Oracle提供JRE和JDK。 - mmmmmm
@Mark 我安装了JRE。 - DGolberg
我正在尝试避免安装JDK,因为在使用JDK的机器上运行的代码正常运行,而在使用JRE的机器上却出现了奇怪的问题...不过那是另一个话题。 - DGolberg
1
从Java 8开始,Oracle Java的这个问题应该得到了很大改善。 - Thorbjørn Ravn Andersen
4个回答

136

JDK

在Mac OS上,/usr/bin/java等命令是委托给真正的JDK命令的存根。这些存根尊重您的JAVA_HOME环境变量的设置,但为了使其工作,您需要安装JDK(从http://www.oracle.com/technetwork/java/javase/downloads/index.html),而不是JRE(从http://java.com)。

JDK安装到/Library/Java/JavaVirtualMachines/jdk1.7.0_NN.jdk(NN的值取决于版本),因此将JAVA_HOME环境变量设置为/Library/Java/JavaVirtualMachines/jdk1.7.0_NN.jdk/Contents/Home以便让/usr/bin/java使用1.7。您可以通过将JAVA_HOME指向/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home来轻松切换回1.6。您可以使用/usr/libexec/java_home工具自动查找正确的值,例如要使/usr/bin/java使用Java 7,可以执行以下操作:

export JAVA_HOME=`/usr/libexec/java_home -v '1.7*'`

要让它使用Java 6,您可以执行以下操作:

export JAVA_HOME=`/usr/libexec/java_home -v '1.6*'`
同样适用于Java 8(使用-v'1.8*')。这将选择与相关主版本匹配的最新安装的JDK,您无需在安装更新时手动更改NN

JRE

如果您想要从命令行运行1.7或1.8JRE,它可以在/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java中找到。这是一个固定路径,您每次只能安装一个“公共”JRE。

$ /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java -version
java version "1.7.0_13"
Java(TM) SE Runtime Environment (build 1.7.0_13-b20)
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)

你可以在你的.bashrc文件中使用一个Shell别名。

alias java_jre='/Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java'

4
谢谢Ian!这解决了我如何让终端使用Java 1.7的难题。 - vichsu
由于某种奇怪的原因,当你发布消息时,我没有收到任何提醒(或者我可能检查了其他地方而错过了它)。不过我已经尝试了这个方法,目前看起来对我也有效。谢谢你,Ian! - DGolberg
1
那个别名正是我需要的,让一切都很好地运行。谢谢! - emkman

12

问题在于Oracle的JRE安装不会更改/usr/bin/java可执行文件。如果您想使用此Java,则必须使用/Library下的路径(需要找到这个路径,我已经安装了JDK,所以可能不同)

根据Oracle的JRE installation document

从Oracle安装JRE将不会更新java-version符号链接或将java添加到您的路径中。为了能够做到这一点,您需要安装JDK。

Oracle JDK确实会更改/usr/bin/java以指向Java 7可执行文件。如果您正在进行开发,则应使用此选项,因为它包括比JRE更多的内容。

Oracle install FAQ 表示

如果您计划运行Java应用程序,请安装Java运行时环境(JRE),也称为Oracle Java。一旦安装了JRE,您可以通过双击JAR文件、JNLP文件和浏览器启动Java小程序和应用程序。请注意,不支持32位浏览器(如32位模式下的Firefox和Chrome)。如果您计划编写Java应用程序,请安装Java开发工具包(JDK)。

我在Windows机器上进行开发,因为这对我来说更容易。Mac目前仅用于问题查找。例如,我的程序的某个用户可以运行该程序(一个swing应用程序),但是某些关于shutdownhook的代码在他安装JDK之前不执行;我正在尝试在这个测试平台上找出原因,但终端中的JRE不正确,因此由于开发机器和测试机器之间的版本差异(从终端运行时)在到达该点之前就会出错。 - DGolberg
我安装了JDK,但它没有改变我的路径。使用的是OSX 10.9.1。 - Deepend
它不会改变路径,只是更新了 /usr/bin/java 运行的内容。 - mmmmmm
在Mac OS X Yosemite(10.10.2)上,我安装了JRE和JDK 8u40。关闭终端并重新打开后,我尝试运行的Java程序可以工作。谢谢提供的信息。 - Chris Smith

5

首先,您是否退出了控制台并重新打开它,以便有机会将路径变量的更改应用?

如果您已经这样做了,请检查您的Java的默认版本:

dwilches@ ~$ cd /System/Library/Frameworks/JavaVM.framework/Versions/
dwilches@ Versions$ ls -l
lrwxr-xr-x  1 root  wheel   59 Mar 19 10:07 CurrentJDK -> /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents
lrwxr-xr-x  1 root  wheel   10 Mar 19 10:07 1.6.0 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 Mar 19 10:07 1.6 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 Mar 19 10:07 1.5.0 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 Mar 19 10:07 1.5 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 Mar 19 10:07 1.4.2 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 Mar 19 10:07 1.4 -> CurrentJDK
lrwxr-xr-x  1 root  wheel    1 Mar 19 10:08 Current -> A
drwxr-xr-x  8 root  wheel  272 Mar 25 10:03 A

现在,你可以看到“当前”版本是“A”(也就是我的Java7)。如果我想将其更改为Java 1.6,那么我可以写:

dwilches@ Versions$ sudo unlink Current
dwilches@ Versions$ sudo ln -s 1.6 Current

然后:

dwilches@ Versions$ java -version
java version "1.6.0_43"
Java(TM) SE Runtime Environment (build 1.6.0_43-b01-447-11M4203)
Java HotSpot(TM) 64-Bit Server VM (build 20.14-b01-447, mixed mode)

因此,您可以使用此方法将“当前位置”指向所需的Java位置。

是的,甚至重新启动了整个系统;仍然显示版本为1.6.0_43。 - DGolberg
你能发布以下这3个命令的结果吗: (1) ls -l /System/Library/Frameworks/JavaVM.framework/Versions/ (2) whereis java (3) ls -ld /usr/bin/java - Daniel
更新原帖...忘记了可以在这个网站上编辑原帖。 - DGolberg
“Current”已经更新了,但是你代码片段中的“CurrentJDK”仍然是1.6.0……很抱歉这个问题对我来说很老套,但仍然存在。 - redfox05

-1
就像Ian所说的那样,但是你可能希望从.sh脚本中调用java7,因此你需要在.bash_profile中添加一个函数而不是别名:
java7() {
    /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java "$@"
}
export -f java7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接