Maven $JAVA_HOME is not defined correctly on Mac OS

This article shows how to fix the Maven error JAVA_HOME is not defined correctly.

Terminal

$ mvn -version
Error: JAVA_HOME is not defined correctly.
  We cannot execute /usr/libexec/java_home/bin/java  

1. $JAVA_HOME and macOS 10.15 Catalina, macOS 11 Big Sur

On macOS 10.15 Catalina and later, the default Terminal shell is zsh. For the zsh shell, we can put the environment variables at ~/.zshenv or ~/.zshrc.

Terminal

% nano ~/.zshenv
~/.zshenv

export JAVA_HOME=$(/usr/libexec/java_home)
Terminal

% source ~/.zshenv

% mvn -version

Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /usr/local/Cellar/maven/3.6.3_1/libexec
Java version: 1.8.0_275, vendor: Oracle Corporation,
runtime: /usr/local/Cellar/openjdk@8/1.8.0+275/libexec/openjdk.jdk/Contents/Home/jre
Default locale: en_MY, platform encoding: UTF-8
OS name: "mac os x", version: "11.1", arch: "x86_64", family: "mac"

2. $JAVA_HOME and older Mac OS

Before macOS 10.15 Catalina, the default Termina shell is bash. For the bash shell, we can put the environment variables at ~/.bash_profile or ~/.bashrc.

Open the ~/.bash_profile

Terminal

$ nano ~/.bash_profile

Add the following content

~/.bash_profile

export JAVA_HOME=$(/usr/libexec/java_home)

Source the file and print the $JAVA_HOME

Terminal

$ source ~/.bash_profile

$ mvn -version

Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /usr/local/Cellar/maven/3.6.3_1/libexec
Java version: 1.8.0_275, vendor: Oracle Corporation,
runtime: /usr/local/Cellar/openjdk@8/1.8.0+275/libexec/openjdk.jdk/Contents/Home/jre
Default locale: en_MY, platform encoding: UTF-8
OS name: "mac os x", version: "11.1", arch: "x86_64", family: "mac"

References

25 comments on “Maven $JAVA_HOME is not defined correctly on Mac OS

  1. Thanks so much! Feeling like a config wizard now 😀

    Reply
  2. Follow this link : https://stackoverflow.com/a/44564303/5005676
    If you see the mvn script: The code fails here —

    Steps for debugging and fixing:

    Step 1: Open the mvn script /Users/Username/apache-maven-3.0.5/bin/mvn (Open with the less command like: less /Users/Username/apache-maven-3.0.5/bin/mvn)

    Step 2: Find out the below code in the script:

    if [ -z “$JAVACMD” ] ; then
    if [ -n “$JAVA_HOME” ] ; then
    if [ -x “$JAVA_HOME/jre/sh/java” ] ; then
    # IBM’s JDK on AIX uses strange locations for the executables
    JAVACMD=”$JAVA_HOME/jre/sh/java”
    else
    JAVACMD=”$JAVA_HOME/bin/java”
    fi
    else
    JAVACMD=”which java
    fi
    fi

    if [ ! -x “$JAVACMD” ] ; then
    echo “Error: JAVA_HOME is not defined correctly.”
    echo ” We cannot execute $JAVACMD”
    exit 1
    fi

    Step3: It is happening because JAVACMD variable was not set. So it displays the error.

    Note: To Fix it

    export JAVACMD=Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/bin/java

    export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/

    Key: If you want it to be permanent open emacs.profile

    post the commands and press Ctrl-x Ctrl-c ( save-buffers-kill-terminal ).

    Reply
  3. You are so amazing mkyong. The problems and crisp solutions that you give in your articles are simply great.

    Reply
  4. Thank you. This worked for me. I believe this works because /usr/libexec/java_home is a symbolic link to the actual JAVA_HOME location. Wrapping it in $() resolves the path during execution. Correct?

    Reply
    1. Not quite: java_home is an executable. When you run it, it prints the path to the Java installation to stdout. The $() is bash functionality that executes a command and returns what was printed to stdout.

      Reply
  5. I accidentally deleted my /lib/exec/java_home. I’d rather replace it than hard-set JAVA_HOME. What are the contents?

    Reply

Leave a Comment

Your email address will not be published. Required fields are marked *