/usr/libexec/java_home is completely broken on Big Sur

Is /usr/libexec/java_home working on Big Sur for anyone?
It won't output anything unless the JAVA_HOME environment variable is already set. When querying for the home folder for a specific version of the JDK, it always just returns the current value of the JAVA_HOME environment variable. Since the only useful purpose of the java_home tool is to get a value for setting JAVA_HOME, this is somewhat backwards and useless.

I reported this against Big Sur betas but that didn't get anywhere. In one case I was actually told it was working as designed, which is clearly not the case.
Post not yet marked as solved Up vote post of swpalmer Down vote post of swpalmer
6.3k views

Answers

I'm facing the same problem exactly like yours with a new fresh installed Big Sur.
Try listing all VMs installed using the java_home utility (capital '-V' option):
Code Block bash
/usr/libexec/java_home -V

Here's output on my system (as an example):
Code Block text
Matching Java Virtual Machines (4):
15.0.1 (x86_64) "AdoptOpenJDK" - "AdoptOpenJDK 15" /Library/Java/JavaVirtualMachines/adoptopenjdk-15.jdk/Contents/Home
11.0.9 (x86_64) "AdoptOpenJDK" - "AdoptOpenJDK 11" /Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
11.0.8 (x86_64) "GraalVM Community" - "GraalVM CE 20.2.0" /Library/Java/JavaVirtualMachines/graalvm-ce-java11-20.2.0/Contents/Home
1.8.0_275 (x86_64) "AdoptOpenJDK" - "AdoptOpenJDK 8" /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
/Library/Java/JavaVirtualMachines/adoptopenjdk-15.jdk/Contents/Home

When selecting a specific version, you might want to enclose it into quotes, e.g.:
Code Block bash
/usr/libexec/java_home -v "11.0.8"
/Library/Java/JavaVirtualMachines/graalvm-ce-java11-20.2.0/Contents/Home

I did notice that if you have JAVA_HOME already set, the "/usr/libexec/java_home -v 'VERSION'" does not return the path to the specified version but returns whatever is in JAVA_HOME. So to remedy that, just unset JAVA_HOME and then set it to whatever you want.
Code Block bash
unset JAVA_HOME
export JAVA_HOME=$(/usr/libexec/java_home -v "11.0.8")

This was not the case in the previous macOS version.

I am running macOS Big Sur, Version 11.0.1

Add a Comment
me too.

if already set $JAVA_HOME, /usr/libexec/java_home -v {{VERSION}} return $JAVA_HOME

so i just vim ~/.zprofile

Code Block shell
#alias setJDK7='unset JAVA_HOME;export JAVA_HOME=`/usr/libexec/java_home -v 1.7`'
alias setJDK8='unset JAVA_HOME;export JAVA_HOME=`/usr/libexec/java_home -v 1.8`'
alias setJDK11='unset JAVA_HOME;export JAVA_HOME=`/usr/libexec/java_home -v 11`'


In my case if JAVA_HOME is not set, then the java_home command will not output anything at all.
Even the -V option or --xml option that lists what is available doesn't work unless JAVA_HOME is already set to a valid JDK folder.
I should correct my last comment. If JAVA_HOME is completely unset, then it is possible to get useful output from /usr/lib/java_home. However, if it is set to a value that is not a valid path to one of the installed JDKs, then the java_home command will not function at all. This includes if JAVA_HOME is set to an empty string (which is why I was a bit confused before). If JAVA_HOME is set to an empty string or an invalid path, /usr/libexec/java_home is useless.
This is a significant change in behaviour from prior versions of macOS.
I've got a slightly different behavior. For some reason javahome will always return "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home" regardless of what I give it with the -v flag.

If I say "java
home -V", it will show all the VMs...

$ /usr/libexec/java_home -V

Code Block
Matching Java Virtual Machines (5):
15 (x86_64) "AdoptOpenJDK" - "AdoptOpenJDK 15" /Library/Java/JavaVirtualMachines/adoptopenjdk-15.jdk/Contents/Home
13.0.1 (x86_64) "Oracle Corporation" - "Java SE 13.0.1" /Library/Java/JavaVirtualMachines/jdk-13.0.1.jdk/Contents/Home
11.0.5 (x86_64) "Oracle Corporation" - "Java SE 11.0.5" /Library/Java/JavaVirtualMachines/jdk-11.0.5.jdk/Contents/Home
1.8.271.09 (x86_64) "Oracle Corporation" - "Java" /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home
1.8.0_271 (x86_64) "Oracle Corporation" - "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_271.jdk/Contents/Home


But again, no matter what I try to do to get a real JDK, it always gives the same /Library/Internat Plug-ins directory, which isn't a full JDK, so all development apps break.
[Replying to Jyong's initial post] 

Same here. Interestingly, iirc, the first time I experienced the error ("The "c++filt" command requires the command line developer tools.") didn't appear until almost 24 hours after my upgrade from Catalina to Big Sur.
I am also facing the same issue.Please suggest the possible solution.
The problem of /usr/libexec/javahome not working correctly if JAVAHOME is set is one problem, and you can hack that in your shell profile by unsetting JAVAHOME before running it.

However, this doesn't fix the problem of applications launched via the GUI. Most of those don't work.
Hacking individual ones to make setting the JAVA
HOME variable then exposes the next problem:

JAVA_HOME contains /Library/Internet Plug-Ins/JavaAppletPlugin.plugin

Note the space. So things just **** up later. Someone needs to learn that spaces in file/directory names are NOT a good idea in Unix based systems.
Still no new from @Apple ?
I'm still completely blocked

  • 1 The problem still persists!

I'm also facing this problem.so no one can fix it ?
Same issue, fixed by following this Stack Overflow answer: https://stackoverflow.com/a/64917842

TLDR, java_home is how affected by environment variable JAVA_HOME and reports this value, ignoring the parameter. It appears to me this is a bug.

You can get around it by unsetting env var JAVA_HOME before using, e.g.

Code Block bash
unset JAVA_HOME ; /usr/libexec/java_home -v 1.8


^ this works for me as I have JDK 8 and 15 installed.
If you have a oracle JDK or JRE installed shit will hit the fan. I've had the same issue.

You can check if oracle is hijacking your system with:
Code Block bash
$/usr/libexec/java_home -V
Matching Java Virtual Machines (4):
15.0.1 (x86_64) "UNDEFINED" - "OpenJDK 15.0.1" /usr/local/Cellar/openjdk/15.0.1/libexec/openjdk.jdk/Contents/Home
1.8.191.12 (x86_64) "Oracle Corporation" - "Java" /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home
1.8.0_275 (x86_64) "Amazon" - "Amazon Corretto 8" /Users/hellothere/Library/Java/JavaVirtualMachines/corretto-1.8.0_275/Contents/Home
1.8.0_272 (x86_64) "Amazon" - "Amazon Corretto 8" /Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home
/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home


You can fix this by a self-uninstall tool called "rm -rf". After that "/usr/libexec/java_home" will behave as you expect it to.

Code Block bash
sudo rm -fr /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin 
sudo rm -fr /Library/PreferencePanes/JavaControlPanel.prefpane


Just for your ease, I use the following script in my .zprofile to easily switch JDK:

Code Block bash
# Simple function allowing you to easyly switch version of java
function setjdk() {
if [ $# -ne 0 ]; then
removeFromPath '/System/Library/Frameworks/JavaVM.framework/Home/bin'
if [ -n "${JAVA_HOME+x}" ]; then
removeFromPath $JAVA_HOME
fi
unset JAVA_HOME
export JAVA_HOME=`/usr/libexec/java_home -v $@`
export PATH=$JAVA_HOME/bin:$PATH
fi
}
function removeFromPath() {
export PATH=$(echo $PATH | sed -E -e "s;:$1;;" -e "s;$1:?;;")
}
setjdk 1.8 # set initial version


A few of the replies before this have what may work for you. Some tools need the environment variable JAVA_HOME set. If your ~/.bash_profile or equivalent is where your JAVA_HOME
is set, for example:

export JAVA_HOME=/usr/libexec/java_home -v 1.8


Then you may want to edit your environment file to use your preferred java version which you can find using

/usr/libexec/java_home -V



Then edit ~/.bash_profile for that version:

export JAVA_HOME=/Library/Java/JavaVirtualMachines/<your java version>/Contents/Home



Note that the terms of use for the Oracle java have changed if you use java professionally, and
there are options that they offer if so - a commercially licensed version through them or that
you can download openjdk instead.