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

Chr*_*ltz 103 java macos java-home

(不确定这是否应该继续使用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
Run Code Online (Sandbox Code Playgroud)

大.

但是,运行:

$ java -version
Run Code Online (Sandbox Code Playgroud)

返回:

java version "1.8.0-ea"
Run Code Online (Sandbox Code Playgroud)

这意味着Java的默认版本目前是预发布版本,它打破了一些"普通"软件包(在我的情况下,VisualVM).

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

那么,是否有一个我可以编辑的文件,我可以在全局设置我的JVM订购首选项?

(请不要告诉我启动Java Preferences Panel,因为它根本不起作用:它不包含任何有用的东西,只列出我安装的4个JVM之一.)

更新:

Oracle JVM存在于/Library/Java/JavaVirtualMachines.重命名JDK 1.8目录jdk1.8.0.jvm.xyz不会改变任何东西:java_home仍然在正确的位置找到它,并且运行/ usr/bin/java仍然执行1.8 JVM.这不是synlinks等的问题.

类似问题的答案

虽然这个答案提供的东西相当于一个黑客,它将删除java_home中的Java版本,但它仍然没有回答java_home 如何选择其默认值以及用户是否可以非破坏性地设置它的问题.

Ian*_*rts 89

我认为这JAVA_HOME是你能做的最好的事情.命令行工具,如javajavac将尊重环境变量,你可以用/usr/libexec/java_home -v '1.7*'给你一个合适的值投入JAVA_HOME,以使命令行工具,使用Java 7.

export JAVA_HOME="`/usr/libexec/java_home -v '1.7*'`"
Run Code Online (Sandbox Code Playgroud)

但标准的双击应用程序包不使用根据安装的JDK /Library/Java..app使用Apple的旧式捆绑包JavaApplicationStub将使用Apple Java 6 /System/Library/Frameworks,而使用AppBundler而不使用捆绑JRE 构建的新式捆绑包将使用"公共"JRE /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home- 在存根代码中硬编码并且无法更改,并且您不能同时安装两个不同的公共JRE.


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

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

visualvm_jdkhome="`/usr/libexec/java_home -v '1.7*'`"
Run Code Online (Sandbox Code Playgroud)

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

  • 我不明白为什么系统偏好设置 Java 控制面板不只是提供一个可供选择的列表,而不必求助于 shell 脚本/命令。我怀疑这仅适用于在浏览器中运行的小程序... (2认同)

voi*_*256 50

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

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

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

我认为我们唯一可能做的就是改变plist:sudo vi /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Info.plist然后将JVMVersion修改1.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' -->`
Run Code Online (Sandbox Code Playgroud)

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

/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
Run Code Online (Sandbox Code Playgroud)

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

java -version
java version "1.7.0_45"
Run Code Online (Sandbox Code Playgroud)

:-)

当然我不知道现在是否还有其它东西,或者1.8.0-ea版本的java是否仍能正常工作.

您可能不应该这样做,而是简单地卸载1.8.0.

但到目前为止,这对我有用.

  • 摘自 [Installation of the JDK and the JRE on macOS](https://docs.oracle.com/javase/10/install/installation-jdk-and-jre-macos.htm):为 macOS 2012 安装 Java 之后-006, `/usr/bin/java` 将找到安装的**最新** JDK,并将其用于 `/usr/bin` 中所有与 Java 相关的命令行工具。 (3认同)

Dan*_*ers 15

实际上,我在反汇编程序中对此进行了一些研究,因为源代码不可用。

/usr/bin/java 和 /usr/libexec/java_home 都使用 JavaLaunching.framework。JAVA_HOME 环境变量确实首先由 /usr/bin/java 和朋友检查(但不是 /usr/libexec/java_home)。框架使用 JAVA_VERSION 和 JAVA_ARCH 环境变量来过滤可用的 JVM。所以,默认情况下:

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (2):
    11.0.5, x86_64: "Amazon Corretto 11"    /Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home
    1.8.0_232, x86_64:  "Amazon Corretto 8" /Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home
Run Code Online (Sandbox Code Playgroud)

但是设置 JAVA_VERSION 可以覆盖默认值:

$ JAVA_VERSION=1.8 /usr/libexec/java_home
/Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home
Run Code Online (Sandbox Code Playgroud)

您还可以设置 JAVA_LAUNCHER_VERBOSE=1 来查看一些额外的调试日志记录,例如搜索路径、找到的 JVM 等,以及 /usr/bin/java 和 /usr/libexec/java_home。

过去,JavaLaunching.framework 实际上使用首选项系统(在 com.apple.java.JavaPreferences 域下)来设置首选 JVM 顺序,允许使用 PlistBuddy 设置默认 JVM - 但据我所知,代码已在最新版本的 macOS 中删除。环境变量似乎是唯一的方法(除了编辑 JDK 包本身中的 Info.plist 之外)。

如果您需要在会话级别设置默认环境变量,当然可以通过 .profile 或launchd来完成。

  • 这是很好的信息,丹。使用“.profile”对于我的用例(例如从启动板启动应用程序)没有用,但“launchd”的提示是一个很好的提示。我必须尝试一下,因为 Java 最近版本控制的疯狂意味着我同时安装了几代 Java,并且(个人)信任级别各不相同。 (2认同)

Yun*_*ska 8

我测试了“jenv”和其他诸如设置“JAVA_HOME”之类的东西,但没有成功。现在我最终得到以下解决方案:

function setJava {
    export JAVA_HOME="$(/usr/libexec/java_home -v $1)"
    launchctl setenv JAVA_HOME $JAVA_HOME
    sudo ln -nsf "$(dirname ${JAVA_HOME})/MacOS" /Library/Java/MacOS 
    java -version
}
Run Code Online (Sandbox Code Playgroud)

(添加到 ~/.bashrc 或 ~/.bash.profile 或 ~/.zshrc)

并这样调用:

setJava 1.8
Run Code Online (Sandbox Code Playgroud)

java_home 将处理错误的输入。所以你不能做错事。Maven 和其他东西现在将选择正确的版本。


Use*_*404 7

这实际上非常简单.假设我们在JavaVirtualMachines文件夹中有这个:

  • jdk1.7.0_51.jdk
  • jdk1.8.0.jdk

想象一下1.8是我们的默认值,然后我们只添加一个新文件夹(例如'old')并将默认的jdk文件夹移动到该新文件夹.再做java -version一次,瞧,1.7!


jry*_*uer 5

这很简单,如果你不介意卷起袖子...... / Library/Java/Home是JAVA_HOME的默认设置,它只是指向以下之一的链接:

  • /System/Library/Java/JavaVirtualMachines/1.?.?.jdk/Contents/Home
  • /Library/Java/JavaVirtualMachines/jdk1.?.?_??.jdk/Contents/Home

所以我想在改变JAVA_HOME内容的情况下更改我的默认JVM/JDK版本.../Library/Java/Home是当前JVM/JDK的标准位置,这就是我想保留的......在我看来以最少的副作用改变事物的最简单方法.

这其实很简单.为了改变你用java -version看到的java版本,你所要做的就是这个版本的一些版本:

cd /Library/Java
sudo rm Home
sudo ln -s /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home ./Home
Run Code Online (Sandbox Code Playgroud)

我没有花时间,但是一个非常简单的shell脚本,它使用/ usr/libexec/java_home和ln重新指定上面的符号链接应该很容易创建愚蠢......

一旦你改变了/ Library/Java/Home指向的位置......你得到了正确的结果:

cerebro:~ magneto$ java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27) Java HotSpot(TM)
64-Bit Server VM (build 25.60-b23, mixed mode)
Run Code Online (Sandbox Code Playgroud)