macOS 如何定位 JAVA_HOME
多数的 Java 入门教程都是要求同时设置 JAVA_HOME 和 PATH(包含 $JAVA_HOME/bin) 两个环境变量,反正两个都有了就保险。其实一般情况下系统能在 PATH 中找到 java 程序时就知道 JAVA_HOME, 基本上只要配置 PATH 就行,而 JAVA_HOME 环境变量是可选的。但也有例外,比如 TOMCAT 就可能要求有 JAVA_HOME 环境变量。
在 macOS 下,JAVA_HOME 与 PATH 的关系又显得有点微妙了。一个新的 macOS 系统,它自带有 java 命令
macOS 定位 JAVA_HOME 有一个自己的命令
列出来两个 JDK, 但选择了 JDK 11
再来一个 JDk
看来在 /Library/Java/JavaVirtualMachines 中有多个 JDK 版本时,/usr/libexec/java_home 会选择最高版本。
比如我们在 /Library/Java/JavaVirtualMachines 中有三个 JDK 版本时,想用 JDK 8
除了 /usr/libexec/java_home -V 可列出 /Library/Java/JavaVirtualMachines 中的所有 JDK 版本及路径,以及首选的 JDK 外,用 /usr/libexec/java_home -X 能以 plist XML 格式展示所有 JDK
还能用 /usr/libexec/java_home -v xxx 智能的显示所对应版本的 JAVA_HOME
然后执行 switch_java 来切换
最后注意在用 /usr/libexec/java_home 定位 JAVA_HOME 时不需要为 JAVA 定制 PATH,要以 /usr/bin/java 作为入口。
javac 也一样
如果有 JDK 中无法被 /usr/bin 下 j* 覆盖的命令,就要从 $JAVA_HOME/bin 中找,所以必要时在修改 JAVA_HOME 环境变量后,也应更新 PATH 环境变量。
关于 Linux 下如何找到 JAVA_HOME, 有两个命令
链接:
永久链接 https://yanbin.blog/macos-how-to-locatate-java_home/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
在 macOS 下,JAVA_HOME 与 PATH 的关系又显得有点微妙了。一个新的 macOS 系统,它自带有 java 命令
$ which java你要直接执行它的话
/usr/bin/java
$ java所以它实际上只是执行 java 的辅助入口,没有实际的 JDK 或 JRE 是没用的。
The operation couldn’t be completed. Unable to locate a Java Runtime.
Please visit http://www.java.com for information on installing Java.
用 PATH 覆盖 /usr/bin/java
当我们把 JDK 安装在非默认目录,如 /Users/yanbin/amazon-corretto-11.jdk,我们可以配置 PATH 来使用这个 JDKexport PATH=/Users/yanbin/amazon-correto-11.jdk/Contents/Home/bin:$PATH然后可以执行
$ java -version注意自己的路径要放在 $PATH 之前,否则仍然会执行 /usr/bin/java, 从而找不到 Java
openjdk version "11.0.14.1" 2022-02-08 LTS
macOS 定位 JAVA_HOME 有一个自己的命令
/usr/libexec/java_home, /usr/bin/java 就是仰赖于它来定位 JAVA_HOME 的。如果 JDK 在非默认目录中,/usr/libexec/java_home 是不知道的$ /usr/libexec/java_home虽然依据 PATH 是可以执行 java 程序的。
The operation couldn’t be completed. Unable to locate a Java Runtime.
Please visit http://www.java.com for information on installing Java.
/usr/libexec/java_home 定位
前面提到 macOS 的 JDK 安装默认目录,那就是/Library/Java/JavaVirtualMachines, JDK 安装程序会安装 JDK 到该目录中,如/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk这时候我们不需要配置 PATH 环境变量(把 PATH 环境变量恢复成默认,或打开一个新的终端),再执行 /usr/libexec/java_home 就能找到该默认位置下的 JDK11
$ /usr/libexec/java_home执行 java
/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home
$ java -version不光是执行 JDK 安装程序的方式,就是我们直接解压 JDK 到目录也行。例如我们解压 JDK 8 到该目录中
openjdk version "11.0.14.1" 2022-02-08 LTS
$ ls /Library/Java/JavaVirtualMachines看看此时 macOS 会选择哪个 JDK
amazon-corretto-11.jdk amazon-corretto-8.jdk
1$ /usr/libexec/java_home
2/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home
3$
4$ /usr/libexec/java_home -V
5Matching Java Virtual Machines (2):
611.0.14.1 (x86_64) "Amazon.com Inc." - "Amazon Corretto 11" /Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home
71.8.0_322 (x86_64) "Amazon" - "Amazon Corretto 8" /Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home
8/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home
9$
10$java -version
11openjdk version "11.0.14.1" 2022-02-08 LTS列出来两个 JDK, 但选择了 JDK 11
再来一个 JDk
$ ls /Library/Java/JavaVirtualMachines
amazon-corretto-11.jdk amazon-corretto-17.jdk amazon-corretto-8.jdk
1$ /usr/libexec/java_home -V
2Matching Java Virtual Machines (3):
3 17.0.2 (x86_64) "Amazon.com Inc." - "Amazon Corretto 17" /Library/Java/JavaVirtualMachines/amazon-corretto-17.jdk/Contents/Home
4 11.0.14.1 (x86_64) "Amazon.com Inc." - "Amazon Corretto 11" /Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home
5 1.8.0_322 (x86_64) "Amazon" - "Amazon Corretto 8" /Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home
6/Library/Java/JavaVirtualMachines/amazon-corretto-17.jdk/Contents/Home<br/><br/>
7$ java -version
8openjdk version "17.0.2" 2022-01-18 LTS看来在 /Library/Java/JavaVirtualMachines 中有多个 JDK 版本时,/usr/libexec/java_home 会选择最高版本。
用 JAVA_HOME 选择 JDK 版本
那么如何让 /usr/bin/java 选择自己想要的 JDK 版本呢,设定 JAVA_HOME, 而不是让 /usr/libexec/java_home 自主选择最高的版本。比如我们在 /Library/Java/JavaVirtualMachines 中有三个 JDK 版本时,想用 JDK 8
export JAVA_HOME=/Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home
$ java -version
openjdk version "1.8.0_322"
/usr/libexec/java_home 的高级用法
命令帮助 1$ /usr/libexec/java_home --help
2Usage: java_home [options...]
3 Returns the path to a Java home directory from the current user's settings.<br/><br/>
4Options:
5 [-v/--version <version>] Filter versions (as if JAVA_VERSION had been set in the environment).
6 [-a/--arch <architecture>] Filter architecture (as if JAVA_ARCH had been set in the environment).
7 [-F/--failfast] Fail when filters return no JVMs, do not continue with default.
8 [ --exec <command> ...] Execute the $JAVA_HOME/bin/<command> with the remaining arguments.
9 [-X/--xml] Print full JVM list and additional data as XML plist.
10 [-V/--verbose] Print full JVM list with architectures.
11 [-h/--help] This usage information.除了 /usr/libexec/java_home -V 可列出 /Library/Java/JavaVirtualMachines 中的所有 JDK 版本及路径,以及首选的 JDK 外,用 /usr/libexec/java_home -X 能以 plist XML 格式展示所有 JDK
$ /usr/libexec/java_home -X
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3<plist version="1.0">
4<array>
5 <dict>
6 <key>JVMArch</key>
7 <string>x86_64</string>
8 <key>JVMBundleID</key>
9 <string>com.amazon.corretto.18</string>
10 <key>JVMEnabled</key>
11 <true/>
12 <key>JVMHomePath</key>
13 <string>/Library/Java/JavaVirtualMachines/amazon-corretto-18.jdk/Contents/Home</string>
14 <key>JVMName</key>
15 <string>Amazon Corretto 18</string>
16 <key>JVMPlatformVersion</key>
17 <string>18.0.0</string>
18 <key>JVMVendor</key>
19 <string>Amazon.com Inc.</string>
20 <key>JVMVersion</key>
21 <string>18.0.0</string>
22 </dict>
23 <dict>
24 <key>JVMArch</key>
25 <string>x86_64</string>
26 <key>JVMBundleID</key>
27 <string>com.amazon.corretto.17</string>
28 <key>JVMEnabled</key>
29 <true/>
30 <key>JVMHomePath</key>
31 <string>/Library/Java/JavaVirtualMachines/amazon-corretto-17.jdk/Contents/Home</string>
32 <key>JVMName</key>
33 <string>Amazon Corretto 17</string>
34 <key>JVMPlatformVersion</key>
35 <string>17.0.2</string>
36 <key>JVMVendor</key>
37 <string>Amazon.com Inc.</string>
38 <key>JVMVersion</key>
39 <string>17.0.2</string>
40 </dict>
41 <dict>
42 <key>JVMArch</key>
43 <string>x86_64</string>
44 <key>JVMBundleID</key>
45 <string>com.amazon.corretto.11</string>
46 <key>JVMEnabled</key>
47 <true/>
48 <key>JVMHomePath</key>
49 <string>/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home</string>
50 <key>JVMName</key>
51 <string>Amazon Corretto 11</string>
52 <key>JVMPlatformVersion</key>
53 <string>11.0.14</string>
54 <key>JVMVendor</key>
55 <string>Amazon.com Inc.</string>
56 <key>JVMVersion</key>
57 <string>11.0.14.1</string>
58 </dict>
59 <dict>
60 <key>JVMArch</key>
61 <string>x86_64</string>
62 <key>JVMBundleID</key>
63 <string>com.amazon.corretto.8</string>
64 <key>JVMEnabled</key>
65 <true/>
66 <key>JVMHomePath</key>
67 <string>/Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home</string>
68 <key>JVMName</key>
69 <string>Amazon Corretto 8</string>
70 <key>JVMPlatformVersion</key>
71 <string>1.8</string>
72 <key>JVMVendor</key>
73 <string>Amazon</string>
74 <key>JVMVersion</key>
75 <string>1.8.0_322</string>
76 </dict>
77</array>
78</plist>还能用 /usr/libexec/java_home -v xxx 智能的显示所对应版本的 JAVA_HOME
$ /usr/libexec/java_home -v 1.8结合 /usr/libexec/java_home -v xxx 选项,我们就可以用一个脚本来切换 JAVA_HOME,核心就是
/Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home
$ /usr/libexec/java_home -v 11
/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home
$ /usr/libexec/java_home -v 8
/Library/Java/JavaVirtualMachines/amazon-corretto-18.jdk/Contents/Home
export JAVA_HOME=$(/usr/libexec/java_home -v $1)根据所使用 shell 的不同,比如我们可以在 ~/.bashrc 或 ~/.zshrc 文件中定义一个函数
1switch_java() {
2 JAVA_HOME=$(/usr/libexec/java_home -v $1)
3 if [ -z $2 ]; then
4 echo "switch JAVA_HOME to $JAVA_HOME"
5 fi
6 export JAVA_HOME
7}<br/><br/>
8# set default JAVA_HOME
9switch_java 11 XX然后执行 switch_java 来切换
$ switch_java 11Demo
$ switch_java 1.8
$ switch_java 17
$ java -version如果把 export JAVA_HOME=$(/usr/libexec/java_home -v $1) 定义在别的脚本文件中要用 source switch_java.sh 1.8 来切换
openjdk version "11.0.14.1" 2022-02-08 LTS
OpenJDK Runtime Environment Corretto-11.0.14.10.1 (build 11.0.14.1+10-LTS)
OpenJDK 64-Bit Server VM Corretto-11.0.14.10.1 (build 11.0.14.1+10-LTS, mixed mode)
$ switch_java 1.8
switch JAVA_HOME to /Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home
$ java -version
openjdk version "1.8.0_322"
OpenJDK Runtime Environment Corretto-8.322.06.1 (build 1.8.0_322-b06)
OpenJDK 64-Bit Server VM Corretto-8.322.06.1 (build 25.322-b06, mixed mode)
最后注意在用 /usr/libexec/java_home 定位 JAVA_HOME 时不需要为 JAVA 定制 PATH,要以 /usr/bin/java 作为入口。
javac 也一样
$ which javac更多 /usr/bin 下的 java 命令
/usr/bin/javac
1$ ls /usr/bin/j*
2/usr/bin/jar /usr/bin/javah /usr/bin/jconsole /usr/bin/jhsdb /usr/bin/jmap /usr/bin/jpackage /usr/bin/json_pp /usr/bin/jstack
3/usr/bin/jarsigner /usr/bin/javap /usr/bin/jcontrol /usr/bin/jimage /usr/bin/jmc /usr/bin/jps /usr/bin/json_pp5.18 /usr/bin/jstat
4/usr/bin/java /usr/bin/javapackager /usr/bin/jdb /usr/bin/jinfo /usr/bin/jobs /usr/bin/jrunscript /usr/bin/json_pp5.30 /usr/bin/jstatd
5/usr/bin/javac /usr/bin/javaws /usr/bin/jdeps /usr/bin/jjs /usr/bin/join /usr/bin/jsadebugd /usr/bin/json_xs /usr/bin/jvisualvm
6/usr/bin/javadoc /usr/bin/jcmd /usr/bin/jhat /usr/bin/jlink /usr/bin/jot /usr/bin/jshell /usr/bin/json_xs5.30如果有 JDK 中无法被 /usr/bin 下 j* 覆盖的命令,就要从 $JAVA_HOME/bin 中找,所以必要时在修改 JAVA_HOME 环境变量后,也应更新 PATH 环境变量。
关于 Linux 下如何找到 JAVA_HOME, 有两个命令
1sh-4.2# dirname $(dirname $(readlink -f $(which javac)))
2/usr/lib/jvm/java-11-openjdk-11.0.14.1.1-1.el7_9.x86_64
3sh-4.2# java -XshowSettings:properties -version 2>&1 > /dev/null | grep 'java.home'
4 java.home = /usr/lib/jvm/java-11-openjdk-11.0.14.1.1-1.el7_9.x86_64链接:
永久链接 https://yanbin.blog/macos-how-to-locatate-java_home/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。