I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE COURSE

1. Introduction

In this tutorial, we’re going to talk about an exception that Maven throws when misconfigured: JAVA_HOME should point to a JDK, not a JRE.

Maven is a powerful tool for building code. We’ll look under the hood to understand why this error happens and will see how to solve the issue.

2. The JAVA_HOME Problem

After installing Maven, we have to set the JAVA_HOME environment variable, so the tool knows where to find the JDK commands to execute. Maven goals run the appropriate Java commands against the project’s source code. For example, the most common scenario is to compile the code by executing the javac command.

If JAVA_HOME is not pointing to a valid JDK installation, Maven will throw an error at every execution:

mvn -version

# Output... 
The JAVA_HOME environment variable is not defined correctly
This environment variable is needed to run this program
NB: JAVA_HOME should point to a JDK, not a JRE

3. JDK or JRE

How does Maven verify the JAVA_HOME path?

Before running any goals, Maven checks for the existence of the java command in the path specified by JAVA_HOME or by asking the OS for a default JDK installation. If the file is not found Maven terminates with the error.

Here is the mvn executable check for Linux (Apache Maven v3.5.4):

if [ -z "$JAVA_HOME" ] ; then
    JAVACMD=`which java`
else
    JAVACMD="$JAVA_HOME/bin/java"
fi
 
if [ ! -x "$JAVACMD" ] ; then
    echo "The JAVA_HOME environment variable is not defined correctly" >&2
    echo "This environment variable is needed to run this program" >&2
    echo "NB: JAVA_HOME should point to a JDK not a JRE" >&2
    exit 1
fi

This check may seem reasonable at first glance, but we have to consider that both JDK and JRE have a bin folder and both contain an executable java file.

Therefore, it is possible to configure JAVA_HOME to point to a JRE installation, hiding this particular error and causing problems at a later stage. While the JRE’s main purpose is to run java code, the JDK can also compile and debug. More details on the differences between JDK and JRE can be found in this article.

For this reason, an mvn compile command would fail. Other simpler goals may not, letting the developer think that the environment has been correctly configured.

4. Checking the JAVA_HOME Configuration

It’s pretty simple to check if JAVA_HOME points to an actual JDK. We can either print its content in a terminal, or we can run one of the following shell commands:

4.1. Checking JAVA_HOME on Linux

Just open a terminal and type:

> $JAVA_HOME/bin/javac -version

If JAVA_HOME points to a JDK, the output should look like:

> javac 1.X.0_XX

If JAVA_HOME doesn’t point to a JDK, the OS will throw an error message:

> bash: /bin/javac: No such file or directory

4.2. Checking JAVA_HOME on Windows

Open a command prompt and type:

%JAVA_HOME%\bin\javac -version

If JAVA_HOME points to a JDK, the output should look like:

> javac 1.X.0_XX

If JAVA_HOME doesn’t point to a JDK, the OS will throw an error message:

> The system cannot find the path specified.

5. How to Solve the Issue

First of all, we need to know where to find our JDK:

  • If we installed our JDK distribution using a package installer, we should be able to find the path using the OS search utility
  • If the distribution was a portable one, let’s check the folder where we extracted it

Once we know the path to the JDK, we can set our JAVA_HOME environment variable. For more details based on a particular OS, please follow the instructions in this article.

6. Conclusion

In this brief tutorial, we have discussed the JAVA_HOME should point to a JDK not a JRE Maven error and examined the root cause.

Finally, we discussed how to check your JAVA_HOME environment variable, and how to make sure it points to a JDK.

I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE LESSONS

Leave a Reply

avatar
  Subscribe  
Notify of