Search code examples
javajava-home

Why can I use javac & java without having JAVA_HOME set?


My Java version is :

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)

I don't set JAVA_HOME in my ~/.bash_profile, but I can use both javac and java!

My .bash_profile looks like this:

export EDITOR="vim"
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

export MAVEN_HOME="$HOME/opt/maven"
export PATH="$PATH:$MAVEN_HOME/bin"

If I want to install other version of the JDK like 11,14,15...., how can I use that? Do I need to setJAVA_HOME?

And if I have multiple versions of JDK installed at the same time, how can I use them at different times as needed? What I see on the Internet is to configure Java_ Home, I don't know what to do at all, because I'm worried that after I install several other versions of JDK, they won't work.

I use MacOS Big Sur.


Solution

  • JAVA_HOME is widely misunderstood.

    Java itself (i.e. the java, javac and related executables) doesn't actually care about JAVA_HOME.

    When they are executed they know which JDK to use (the one they are associated with). The only relevant thing is that your shell (or other tool) finds the executables in the first place and for this PATH is used. Note that PATH is a general-purpose variable used by basically all widely used general purpose OS today to find executables. It's not a Java-specific thing.

    In other words: when launching java directly from the shell, only PATH is relevant.

    So why does JAVA_HOME come up so frequently?

    Some third-party tools (such as Gradle, Maven, Tomcat and various others) will use JAVA_HOME to find the appropriate JDK/JRE to execute. Most of the ones that do will fall back to whatever is on the PATH if no JAVA_HOME is set.

    So if you use such a tool and you want to specify a specific Java version then you can set JAVA_HOME as an additional hint.

    It might be a good idea to set JAVA_HOME to point to your preferred Java runtime, but it's not necessary for many things.

    One commonly used pattern is to define a JAVA_HOME to point to your preferred JDK and then use that to set up your PATH. This way the two will be aligned and if the preferred JDK changes, you only need to change it in one point:

    export JAVA_HOME="/some/path/pointing/to/a/jdk"
    export PATH="$JAVA_HOME/bin:$PATH"