(不确定这是否应该继续 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 位于 /Library/Java/JavaVirtualMachines
中。将 JDK 1.8 目录重命名为 jdk1.8.0.jvm.xyz
不会改变任何内容:java_home
仍然在正确的位置找到它,并且运行 /usr/bin/java 仍然执行 1.8 JVM。这不是synlinks等的问题。
类似问题的答案
虽然 this answer 提供了一种相当于 hack 的方法,可以将 Java 版本从 java_home 中移除,但它仍然没有回答 如何 java_home 选择其默认值以及用户是否可以{ 2}。
/usr/bin/java
只是一个符号链接
/usr/bin/java
指向 /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java
。 Versions
目录不包含指向 1.8.0 JDK 的符号链接。相反,它包含一个名为 A
的目录,Current
指向该目录。 A
不是“JAVA_HOME。它有一个名为 Commands
的子目录,它确实有一个 java
命令,但它是一个不透明的通用二进制文件,谁知道什么。我怀疑它使用 java_home
等. 决定使用哪个 JVM。
我认为 JAVA_HOME
是你能做的最好的。 java
和 javac
等命令行工具将尊重该环境变量,您可以使用 /usr/libexec/java_home -v '1.7*'
为您提供合适的值以放入 JAVA_HOME
以使命令行工具使用 Java 7。
export JAVA_HOME="`/usr/libexec/java_home -v '1.7*'`"
但是标准的可双击应用程序包根本不使用安装在 /Library/Java
下的 JDK。使用 Apple 的 JavaApplicationStub
的旧式 .app
捆绑包将使用来自 /System/Library/Frameworks
的 Apple Java 6,而使用 AppBundler 构建但没有捆绑 JRE 的新式捆绑包将使用 /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home
中的“公共”JRE - 这很难-编码在存根代码中并且不能更改,并且您不能同时安装两个不同的公共 JRE。
编辑:我专门查看了 VisualVM,假设您使用的是 the download page 中的“应用程序包”版本,并且这个特定的应用程序不是 AppBundler 应用程序,而是它的主要可执行文件是一个调用数字的 shell 脚本其他 shell 脚本并读取各种配置文件。它默认从 /Library/Java
选择最新的 JDK,只要它是 7u10 或更高版本,或者如果您的 Java 7 安装是更新 9 或更早版本,则使用 Java 6。但是解开 shell 脚本中的逻辑,在我看来,您可以使用配置文件指定特定的 JDK。
创建一个包含该行的文本文件 ~/Library/Application Support/VisualVM/1.3.6/etc/visualvm.conf
(将 1.3.6 替换为您正在使用的任何版本的 VisualVM)
visualvm_jdkhome="`/usr/libexec/java_home -v '1.7*'`"
这将迫使它选择 Java 7 而不是 8。
我也去过那里并到处搜索 /usr/libexec/java_home
的工作原理,但我找不到任何关于它如何确定它列出的可用 Java 虚拟机的信息。
我做了一些实验,我认为它只是执行 ls /Library/Java/JavaVirtualMachines
,然后检查它在那里找到的所有运行时的 ./<version>/Contents/Info.plist
。
然后它通过 Info.plist 中包含的键 JVMVersion
对它们进行降序排序,默认情况下它使用第一个条目作为其默认 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' -->`
然后它神奇地从列表顶部消失:
/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"
:-)
当然,我不知道现在是否有其他问题,或者 java 的 1.8.0-ea 版本是否仍然可以正常工作。
您可能不应该这样做,而只需卸载 1.8.0。
但是到目前为止,这对我有用。
/usr/libexec/java_home -v 1.7
。我想我会为 JAVA_HOME 做同样的事情......
/usr/bin/java
将找到已安装的 最新 JDK,并将其用于 { 3}。
这实际上很容易。假设我们的 JavaVirtualMachines 文件夹中有这个:
jdk1.7.0_51.jdk
jdk1.8.0.jdk
假设 1.8 是我们的默认值,那么我们只需添加一个新文件夹(例如“旧”)并将默认 jdk 文件夹移动到该新文件夹。再做一次java -version
,瞧,1.7!
实际上,我在反汇编程序中看了一点,因为源不可用。
/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
但是设置,比如说, JAVA_VERSION 可以覆盖默认值:
$ JAVA_VERSION=1.8 /usr/libexec/java_home
/Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home
您还可以设置 JAVA_LAUNCHER_VERBOSE=1 以查看一些额外的调试日志,例如搜索路径、找到的 JVM 等,包括 /usr/bin/java 和 /usr/libexec/java_home。
过去,JavaLaunching.framework 实际上使用首选项系统(在 com.apple.java.JavaPreferences 域下)来设置首选 JVM 顺序,allowing the default JVM to be set with PlistBuddy - 但据我所知,该代码最近已被删除macOS 版本。环境变量似乎是唯一的方法(除了在 JDK 包本身中编辑 Info.plist。)
设置默认环境变量当然可以通过您的 .profile 或通过 launchd 完成,如果您需要在会话级别设置它们。
.profile
对我的用例(例如从启动板启动应用程序)没有用处,但 launchd
上的提示是一个很好的提示。我必须尝试一下,因为 Java 最近的版本控制疯狂意味着我同时安装了几代 Java,具有不同程度的(个人)信任。
我测试了“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
}
(添加到 ~/.bashrc 或 ~/.bash.profile 或 ~/.zshrc)
像这样打电话:
setJava 1.8
java_home 将处理错误的输入。所以你不能做错事。 Maven 和其他东西现在会选择正确的版本。
这很简单,如果您不介意卷起袖子... /Library/Java/Home 是 JAVA_HOME 的默认值,它只是指向以下之一的链接:
/System/Library/Java/JavaVirtualMachines/1.?.?.jdk/Contents/Home
/Library/Java/JavaVirtualMachines/jdk1.?.?_??.jdk/Contents/Home
所以我想更改我的默认 JVM/JDK 版本而不更改 JAVA_HOME 的内容... /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
我没有花时间,但是一个非常简单的 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)
/Library/Java/Home
确实是一个符号链接,但它指向 /System/Library/Frameworks/JavaVM.framework/Home
,它本身就是一大堆符号链接,最终让你……一个神奇的命令,确定正确的 JRE发射。请注意,/usr/libexec/java_home
也链接到这个魔法。因此,您可以通过替换符号链接并指向单个 JRE 来中断一切,但您必须每次都更新它。显然没有像 set_preferred_jvm_version
或类似的命令。
JAVA_HOME
。我将尝试使用这种技术,看看它是否会导致基于 Java 的程序使用“首选”Java VM 启动。我怀疑它会,但它非常脆弱。
.bash_profile
中有这个:export JAVA_HOME=`/usr/libexec/java_home -v 12`
Oracle 的 uninstallation instructions for Java 7 为我工作。
摘抄:
卸载 JDK 要卸载 JDK,您必须具有管理员权限并以 root 身份或使用 sudo(8) 工具执行删除命令。导航到 /Library/Java/JavaVirtualMachines 并删除名称与以下格式匹配的目录:* /Library/Java/JavaVirtualMachines/jdk
有点晚了,但因为这是 Mac OSX 的一个持续问题......
我找到的最简单的解决方案是简单地删除 Apple 安装的 OpenJDK 内容。每次 Mac OSX 的更新到达时,它都会被安装,您需要再次将其删除。
如果您在 Mac 上使用 Java 为 Google App Engine 开发应用程序,这将非常有效。 OpenJDK 无法正常运行,Mac OSX Yosemite 升级附带的 Java 版本会导致 Eclipse Plug-in for App Engine 在每次部署时崩溃,并出现有用的错误:“读取超时”。
可以很容易地添加到 java_home。
MacOS上JAVA_HOME的设置方式如下。例如,将以下内容添加到您的 ~/.zshrc 中。该脚本将选择您系统上安装的最新 JDK。
JAVA_HOME=$(/usr/libexec/java_home)
当使用 -V 开关运行 java_home 脚本时,会列出当前安装的 JDK。我的 MacOS (Monterey) 默认 Java Home (JAVA_HOME) 就是这个。
/usr/libexec/java_home -V (Command to list installed JDK versions)
1.8.0_292 (x86_64) "AdoptOpenJDK" - "AdoptOpenJDK 8" /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
从 here 下载 Java OpenJDK 版本。确保下载 JDK .dmg 包。这有一个更新 JAVA_HOME 的安装程序。安装 v18.0 后,我的更改为以下。
/usr/libexec/java_home -V
Matching Java Virtual Machines (2):
18 (x86_64) "Azul Systems, Inc." - "Zulu 18.28.13" /Library/Java/JavaVirtualMachines/zulu-18.jdk/Contents/Home
1.8.0_292 (x86_64) "AdoptOpenJDK" - "AdoptOpenJDK 8" /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
现在它会选择最上面的项目,即版本 18。如果默认的最上面的项目不是优选的,则重新调整名称,以便您想要的名称是第一个列出的,如上面的 void256 所述。排序键在这里。
/Library/Java/JavaVirtualMachines/*/Contents/Info.plist.
现在所有工具都可以使用来自 JAVA_HOME 的 jdk。
java_home
不影响 JAVA_HOME
环境变量。 (2) java_home 总是喜欢最新的版本。当我不想要最新的时,我在问如何设置默认版本。 (3) 这个问题是关于 not 从命令行运行的应用程序,因此环境变量和命令行行为不相关。
编辑:此信息专门针对 visualvm,不适用于任何其他 java 应用程序
正如其他人所说,您需要修改visualvm.conf
对于 Mac 上最新版本的 JvisualVM 1.3.6,安装目录已更改。
它当前位于 /Applications/VisualVM.app/Contents/Resources/visualvm/etc/visualvm.conf 中。
但是,这可能取决于您安装 VisualVM 的位置。找到 VisualVM 的最简单方法是在哪里启动它,然后使用以下命令查看该过程:
ps -ef | grep 视觉虚拟机
你会看到类似的东西:
... -Dnetbeans.dirs=/Applications/VisualVM.app/Contents/Resources/visualvm/visualvm...
您想要获取 netbeans.dir 属性并查找目录,您将找到 etc 文件夹。
在 visualvm.conf 中取消注释此行并更改 jdk 的路径
visualvm_jdkhome="/path/to/jdk"
此外,如果您的 visualvm 运行缓慢并且内存很大,我建议大大增加可用内存量并在服务器模式下运行它:
visualvm_default_options="-J-XX:MaxPermSize=96m -J-Xmx2048m -J-Xms2048m -J-server -J-XX:+UseCompressedOops -J-XX:+UseConcMarkSweepGC -J-XX:+UseParNewGC -J-XX:NewRatio=2 -J-Dnetbeans.accept_license_class=com.sun.tools.visualvm.modules.startup.AcceptLicense -J-Dsun.jvmstat.perdata.syncWaitMs=10000 -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.d3d=false"
~/Library/Application Support/VisualVM/1.3.6/etc/visualvm.conf
加载其配置。
我有类似的情况,以下过程对我有用:
在终端中,输入 vi ~/.profile 然后在文件中添加这一行,并保存 export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk
然后输入 java -version 查看结果
java -version
什么是.profile?来自:http://computers.tutsplus.com/tutorials/speed-up-your-terminal-workflow-with-command-aliases-and-profile--mac-30515
.profile 文件是一个隐藏文件。它是一个可选文件,它告诉系统在其配置文件登录的用户登录时运行哪些命令。例如,如果我的用户名是 bruno,并且 /Users/bruno/ 中有一个 .profile 文件,则它的所有内容将在登录过程中执行。
MacOS 使用 /usr/libexec/java_home 来查找当前的 Java 版本。绕过的一种方法是更改 plist 文件,如上面@void256 所述。其他方法是备份 java_home 并用您自己的脚本 java_home 替换它,代码 echo $JAVA_HOME
现在,通过将以下命令添加到 ~/.bash_profile,将 JAVA_HOME 导出到所需的 SDK 版本。 export JAVA_HOME="/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home" launchctl setenv JAVA_HOME $JAVA_HOME /// 将环境变量设为全局
运行命令 source ~/.bash_profile 来运行上述命令。
任何时候需要更改 JAVA_HOME,他都可以在 ~/.bash_profile 文件中重置 JAVA_HOME 值。
我想将默认的 Java 版本从 1.6* 更改为 1.7*。我尝试了以下步骤,它对我有用:
从 /usr/bin 下删除了链接“java”
再次创建它,指向新位置:
ln -s /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/bin/java java
用“java -version”验证
Java 版本“1.7.0_51”Java(TM) SE 运行时环境(构建 1.7.0_51-b13)Java HotSpot(TM) 64 位服务器 VM(构建 24.51-b03,混合模式)
/usr/libexec/java_home
的行为。
不定期副业成功案例分享
JAVA_HOME
是要走的路,一般来说,你最好的选择是指定在其他情况下你需要的次要版本。根据反汇编,事实证明您可以export JAVA_VERSION=1.7
使java_home
默认显示 JKD7 而不是 JDK8,但这会破坏java_home -v 1.6
,因为java-home
将其解释为附加约束并由于相互无法满足的约束而放弃,然后即使使用--failfast
选项,也只使用默认的 1.8。