如何更改从 /usr/libexec/java_home 返回的 Mac OS 的默认 Java VM

2022-08-31 08:35:44

(不确定这是否应该在SU上...迁移当然是一种选择,但更多的程序员在这里阅读问题,所以这里去了)。

我运行的是Mac OS X 10.8.4,并且安装了Apple的JDK 1.6.0_51以及Oracle的JDK 1.7.0_25。我最近为一些需要它的预发布软件安装了Oracle的1.8预览版JDK。现在,当我运行 /usr/libexec/java_home 时,我得到这个:

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (4):
    1.8.0, x86_64:  "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home
    1.7.0_25, x86_64:   "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home
    1.6.0_51-b11-457, x86_64:   "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    1.6.0_51-b11-457, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

伟大。

但是,正在运行:

$ java -version

返回:

java version "1.8.0-ea"

这意味着Java的默认版本目前是预发布版本,这会破坏一些“正常”包(在我的情况下,VisualVM)。

我无法设置,因为启动应用程序会忽略环境变量,即使从命令行启动(例如)。JAVA_HOME$ open /Applications/VisualVM.app

那么,是否有我可以编辑的文件,我可以在其中全局设置我的JVM排序首选项?

(请不要告诉我启动Java首选项面板,因为这根本不起作用:它不包含任何有用的东西,只列出了我安装的4个JVM中的一个。

更新

Oracle JVM 驻留在 .将 JDK 1.8 目录重命名为不会更改任何内容:仍然在正确的位置找到它,并且运行 /usr/bin/java 仍然执行 1.8 JVM。这不是同步链接等的问题。/Library/Java/JavaVirtualMachinesjdk1.8.0.jvm.xyzjava_home

类似问题的答案

虽然这个答案提供了相当于一个黑客攻击,它将删除java版本,使其不被java_home拾取,但它仍然没有回答java_home如何选择其默认值以及用户是否可以非破坏性地设置它的问题。


答案 1

我认为这是你能做的最好的。命令行工具喜欢并且会尊重该环境变量,您可以使用它来为您提供合适的值,以便使命令行工具使用Java 7。JAVA_HOMEjavajavac/usr/libexec/java_home -v '1.7*'JAVA_HOME

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

但是标准的可双击应用程序捆绑包根本不使用安装在下面的 JDK。使用Apple的旧式捆绑包将使用Apple Java 6 from ,而使用AppBundler构建的新式捆绑包没有捆绑的JRE将使用“公共”JRE - 这是在存根代码中硬编码的,无法更改,并且您不能同时安装两个不同的公共JRE。/Library/Java.appJavaApplicationStub/System/Library/Frameworks/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home


编辑:我专门看了一下VisualVM,假设你正在使用下载页面的“应用程序包”版本,并且这个特定的应用程序不是AppBundler应用程序,而是它的主要可执行文件是一个shell脚本,它调用许多其他shell脚本并读取各种配置文件。它默认从 7u10 或更高版本中选择最新的 JDK,或者如果您的 Java 7 安装是更新 9 或更早版本,则使用 Java 6。但是解开shell脚本中的逻辑,在我看来,你可以使用配置文件指定特定的JDK。/Library/Java

创建一个包含该行的文本文件(将 1.3.6 替换为您正在使用的任何版本的 VisualVM)~/Library/Application Support/VisualVM/1.3.6/etc/visualvm.conf

visualvm_jdkhome="`/usr/libexec/java_home -v '1.7*'`"

这将迫使它选择Java 7而不是8。


答案 2

我也去过那里,到处搜索是如何工作的,但我找不到任何关于它如何确定它列出的可用Java虚拟机的信息。/usr/libexec/java_home

我已经做了一些实验,我认为它只是执行一个,然后检查它在那里找到的所有运行时。ls /Library/Java/JavaVirtualMachines./<version>/Contents/Info.plist

然后,它按 Info.plist 中包含的键对它们进行排序,并且缺省情况下,它使用第一个条目作为其默认 JVM。JVMVersion

我认为我们唯一能做的就是更改plist:然后将JVMVersion从修改为其他内容,使其排序到底部而不是顶部,例如.sudo vi /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Info.plist1.8.0!1.8.0

像这样:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    ...
    <dict>
            ...
            <key>JVMVersion</key>
            <string>!1.8.0</string>   <!-- changed from '1.8.0' to '!1.8.0' -->`

然后它神奇地从列表顶部消失了:

/usr/libexec/java_home -verbose
Matching Java Virtual Machines (3):
    1.7.0_45, x86_64:   "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home
    1.7.0_09, x86_64:   "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_09.jdk/Contents/Home
    !1.8.0, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home

现在,您需要注销/登录,然后:

java -version
java version "1.7.0_45"

:-)

当然,我不知道现在是否有其他东西坏了,或者1.8.0-ea版本的java是否仍然正常工作。

您可能不应该执行任何这些操作,而只是简单地卸载 1.8.0。

然而,到目前为止,这对我有用。