Error java_home is set to an invalid directory usr lib jvm temurin 8 jdk amd64

Ever wondered where Java stuff lives on your Apple Mac? Ever had to find how to set your environment to work with a specific version of Java? Ever manually set the JAVA_HOME environment variable to get something working?

If so, this note may help.

macOS is the operating system that runs on Apple Mac hardware. I have used Java on these machines for many years. A lot of things have changed in that time: Apple used to bundle Java; Oracle bought Sun; Apple stopped bundling Java … macOS was previously known as Mac OS X and later OS X. Oracle still use the old OS X branding.

I have just installed the latest Java upgrade and decided to try to understand how to work with the different versions of Java on macOS. Then I decide to write about it!

I read JDK 8 Installation for OS X from the Java Platform SE Installation Guide some time ago. But I failed to appreciate the java_home command.

This Note for Geeks:

  • describes how to use java_home to set the JAVA_HOME environment variable
  • describes how the java_home --exec <command> can be used to execute Java commands for a specific JDK version independent of JAVA_HOME
  • describes a bash profile to enable interactive setting of the JDK version
  • shares some observations on Java symbolic links on macOS
  • is relevant to Java on macOS and versions of OS X since 2012

See Oracle OS X Platform Install FAQ for further information.

ORACLE — IMPORTANT INFORMATION REGARDING THE SECURITY OF JAVA SE

Earlier versions of Java SE have serious security risks corrected in later versions.

That creates a serious security vulnerability. Even if you installed the most recent version of Java SE, the personal information on your computer may be at risk because earlier, less secure versions could still be executed.

To fix this problem, visit http://java.com/uninstall, where instructions on how to uninstall older versions of Java SE are provided.

java_home

/usr/libexec/java_home is the simplest maintainable way of setting JAVA_HOME on macOS.

You can use java_home to:

  • Find all installed JDKs
  • Get value for JAVA_HOME for a specific JDK version
  • Get the value of JAVA_HOME for the default JDK version
  • Execute specific versions of Java commands

Finding all installed JDKs

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (4):
1.8.0_121, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
1.7.0_45, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home
1.6.0_65-b14-468, x86_64: "Java SE 6" /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
1.6.0_65-b14-468, i386: "Java SE 6" /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

NOTE: I will consider uninstalling the 1.6 versions to remove any associate security vulnerabilities

Getting values for JAVA_HOME for specific JDK versions

$ /usr/libexec/java_home -v 1.6
/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
$ /usr/libexec/java_home -v 1.7
/Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home
$ /usr/libexec/java_home -v 1.8
/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home

Getting the value of JAVA_HOME for the default JDK version

$ /usr/libexec/java_home
/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home

Executing specific versions of Java commands, such as java

java_home is the best way on macOS to execute a Java command ...jdk/Contents/Home/bin/<command> for a specific version of the JDK. And it is independent of the setting of JAVA_HOME.

  • Executing the default version of a java <command>
/usr/libexec/java_home --exec <command>

For example:

$ /usr/libexec/java_home --exec java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
  • Executing a specific version of java command
$ /usr/libexec/java_home -v 1.6 --exec java

For example:

$ /usr/libexec/java_home -v 1.6 --exec java -version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-468-11M4833)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-468, mixed mode)

man java_home

java_home(1)
NAME
java_home - return a value for $JAVA_HOME

-v or --version version
Filters the returned JVMs by the major platform version in "JVMVersion" form.
Example versions: "1.5+", or "1.6*".

-V or --verbose
Prints the matching list of JVMs and architectures to stderr.

--exec command ...
Executes the command at $JAVA_HOME/bin/<command> and passes the remaining arguments.
Any arguments to select which $JAVA_HOME to use must precede the --exec option.

NOTE: The use of $JAVA_HOME in the man page is misleading because:

java_home can be used to return a value that can be used to set $JAVA_HOME

The --exec command can be used to execute a command .../Home/bin/<command> as if it was $JAVA_HOME/bin/<command> without changing or using $JAVA_HOME.

JAVA_HOME

The JAVA_HOME environment variable contains the home location of an installed JDK.

/usr/libexec/java_home is the simplest maintainable way of setting JAVA_HOME.

  • Set JAVA_HOME to JDK version 1.7
export JAVA_HOME=`/usr/libexec/java_home -v 1.7`
  • Set JAVA_HOME to the default JDK
export JAVA_HOME=`/usr/libexec/java_home`
  • Check JAVA_HOME
$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
  • Check the actual java version
$ java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

Independence of java_home --exec from $JAVA_HOME

java_home --exec <command> can be used to execute Java commands independent of the setting of $JAVA_HOME.

The following examples demonstrate executing three different versions of the java command without changing $JAVA_HOME:

  • version using $JAVA_HOME
$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
$ java -version
java version "1.6.0_65"
  • specific version using java_home --exec java -v 1.7
$ /usr/libexec/java_home -v 1.7 --exec java -version
java version "1.7.0_45"
  • default version using java_home --exec java
$ /usr/libexec/java_home --exec java -version
java version "1.8.0_121"

How I use java_home to set JAVA_HOME

This setup is for bash, the Bourne Again Shell on macOS. There are similar variations for other shells.

Set environment variables in .bash_profile

# aliase commands to enable easy setting of JDK version
alias setJDK6='export JAVA_HOME=`/usr/libexec/java_home -v 1.6`'
alias setJDK7='export JAVA_HOME=`/usr/libexec/java_home -v 1.7`'
alias setJDK8='export JAVA_HOME=`/usr/libexec/java_home -v 1.8`'

# set to the default JDK
export JAVA_HOME=`/usr/libexec/java_home`

This profile creates aliases to enable interactive setting of the JDK version and sets JAVA_HOME to the default JDK.

Use the aliases to interactively set JAVA_HOME

Set JAVA_HOME to v 1.7

$ setJDK7

Check $JAVA_HOME

$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home

Check java version

$ java -version
java version "1.7.0_45"

Set JAVA_HOME to v 1.8

$ setJDK8

Check $JAVA_HOME

$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home

Check java version

$ java -version
java version "1.8.0_121"

I got the idea for the aliases from https://wimdeblauwe.wordpress.com/2014/03/20/switching-easily-between-java-jdks-on-mac-os-x/.

I have been lost a few times trying to follow the symbolic linking of Java versions in and out of /System/Library/Frameworks/JavaVM.framework/Versions/ and /Library/Java/JavaVirtualMachines/.

The following are what seem to matter.

Which java

$ which java
/usr/bin/java

The java command is symlinked deep in the JavaVM.framework

$ ls -l /usr/bin/java
/usr/bin/java -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java

The java_home command is symlinked deep in the JavaVM.framework

$ ls -l /usr/libexec/java_home
/usr/libexec/java_home -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java_home

Thanks to https://superuser.com/questions/879601/how-to-recover-usr-libexec-java-home-executable-on-mac-os-x-10-8-5

Assumption

The Java commands in /usr/bin/ appear to execute the corresponding Java commands for JAVA_HOME.

Each Java command /usr/bin/<command> executes $JAVA_HOME/bin/<command>

For example:

/usr/bin/java executes $JAVA_HOME/bin/java

How do I fix Java Home is set to an invalid directory?

To Solve ERROR: JAVA_HOME is set to an invalid directory Error Error Is saying that There is just no need to add bin into PATH variable. You need to set the JAVA_HOME like this. JAVA_HOME=”C:\Program Files\Java\jdk1. 8.0_131″ Just set JAVA_HOME like this and your error will be solved.

How do you fix please set the JAVA_HOME variable in your environment to match the location of your Java installation?

To set JAVA_HOME, do the following: Right click My Computer and select Properties. On the Advanced tab, select Environment Variables, and then edit JAVA_HOME to point to where the JDK software is located, for example, C:\Program Files\Java\jdk1.

Why JAVA_HOME is not working?

Verify JAVA_HOME Enter the command echo %JAVA_HOME% . This should output the path to your Java installation folder. If it doesn't, your JAVA_HOME variable was not set correctly. Please make sure you're using the correct Java installation folder, or repeat the steps above.

What happens if JAVA_HOME is not set?

If any program that requires a Java runtime fails to find the JAVA_HOME environment variable upon startup, or if the JAVA_HOME environment variable is misconfigured, it will result in some of the following error messages to be displayed: A Java installation exists but JAVA_HOME has been set incorrectly.