1375

How can you change the default version of Java on a mac?

5
  • 4
    what does executing /usr/libexec/java_home tell you?
    – Bart
    Commented Feb 23, 2014 at 6:00
  • 2
    /usr/libexec/java_home returns /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    – Venkat
    Commented Feb 23, 2014 at 6:01
  • Could be you just need to reboot. Have you tried that?
    – Bart
    Commented Feb 23, 2014 at 6:04
  • 1
    Yep restarted the computer and the terminal... no change.
    – Venkat
    Commented Feb 23, 2014 at 6:55
  • For those wanting /usr/libexec/java_home to be managed by SDKMAN see this answer: stackoverflow.com/a/76523554/328275
    – axiopisty
    Commented Feb 14 at 18:02

38 Answers 38

2479

First run /usr/libexec/java_home -V which will output something like the following:

Matching Java Virtual Machines (3):
1.8.0_05, x86_64:   "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home
1.6.0_65-b14-462, x86_64:   "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
1.6.0_65-b14-462, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home

Pick the version you want to be the default (1.6.0_65-b14-462 for arguments sake) then:

export JAVA_HOME=`/usr/libexec/java_home -v 1.6.0_65-b14-462`

or you can specify just the major version, like:

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

Now when you run java -version you will see:

java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)

Add the export JAVA_HOME… line to your shell’s init file.

For Bash (as stated by antonyh):

export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)

For Fish (as stated by ormurin)

set -x JAVA_HOME (/usr/libexec/java_home -d64 -v1.8)

Updating the .zshrc file should work:

nano ~/.zshrc

export JAVA_HOME=$(/usr/libexec/java_home -v 1.8.0)

Press CTRL+X to exit the editor Press Y to save your changes

source ~/.zshrc
echo $JAVA_HOME
java -version
29
  • 18
    those really are backticks the export line
    – David West
    Commented Nov 27, 2014 at 19:38
  • 11
    This did not work for me. Grab the path from running java_home -V and add this to the export command, like this export JAVA_HOME="/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home"
    – oden
    Commented Nov 28, 2014 at 1:04
  • 85
    This works in Bash - export JAVA_HOME=$(/usr/libexec/java_home -v 1.8) - also note, java_home allows partial matches so you don't have to include the full version as it'll find the latest installed. This makes updates easier. Commented Dec 24, 2014 at 15:28
  • 22
    Make sure you are using ` ` not ' ' for export.
    – blizzard
    Commented Jan 12, 2015 at 10:49
  • 10
    I wish I could upvote this every time I have to google "os x switch java version" and get back here
    – Raibaz
    Commented Dec 19, 2018 at 16:14
593

This answer is an attempt to address: how to control java version system-wide (not just in currently running shell) when several versions of JDK are installed for development purposes on macOS El Capitan or newer (Sierra, High Sierra, Mojave). As far as I can tell, none of the current answers do that (*).

As a developer, I use several JDKs, and I want to switch from one to the other easily. Usually I have the latest stable one for general use, and others for tests. But I don't want the system (e.g. when I start my IDE) to use the latest "early access" version I have for now. I want to control system's default, and that should be latest stable.

The following approach works with Java 7 to 12 at least (early access at the time of this writing), with Oracle JDK or OpenJDK (including builds by AdoptOpenJDK produced after mid-October 2018).

Solution without 3rd party tools:

  • leave all JDKs at their default location, under /Library/Java/JavaVirtualMachines. The system will pick the highest version by default.
  • To exclude a JDK from being picked by default, rename its Contents/Info.plist to Info.plist.disabled. That JDK can still be used when $JAVA_HOME points to it, or explicitly referenced in a script or configuration. It will simply be ignored by system's java command.

System launcher will use the JDK with highest version among those that have an Info.plist file.

When working in a shell with alternate JDK, pick your method among existing answers (jenv, or custom aliases/scripts around /usr/libexec/java_home, etc).


Details of investigation in this gist.


(*) Current answers are either obsolete (no longer valid for macOS El Capitan or Sierra), or only address a single JDK, or do not address the system-wide aspect. Many explain how to change $JAVA_HOME, but this only affects the current shell and what is launched from there. It won't affect an application started from OS launcher (unless you change the right file and logout/login, which is tedious). Same for jenv, it's cool and all, but as far as I can tell it merely changes environment variables, so it has the same limitation.

20
  • 24
    This is the answer I was looking for, since jenv nor JAVA_HOME are able to set the system-wide java version, i.e. the one Eclipse would use. Commented Jun 2, 2017 at 6:52
  • 4
    @Rodrigo Yes, as mentioned in "Details of investigation" (linked above): "Installing a JDK also overwrites /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/. Apparently this is the one that the new Preferences pane will launch -- this is the only exception I found to my solution: that thingy will still use JDK9 (latest I installed), but no other Java application does."
    – Hugues M.
    Commented Jul 26, 2017 at 13:09
  • 3
    Worth noting that java versions are found in /Library/Java/JavaVirtualMachines, and that the above excellent working solution is within that context. Commented Dec 8, 2017 at 16:53
  • 4
    Exactly, this is the best and the most functional solution for this question. Unfortunately so. Commented Feb 19, 2018 at 13:22
  • 4
    I cannot thank you enough for this answer. This fixed launching applications from the OS launcher. Commented Nov 14, 2018 at 20:05
427

Adding to the above answers, I put the following lines in my .bash_profile (or .zshrc for MacOS 10.15+) which makes it really convenient to switch (including @elektromin's comment for java 9):

alias j20="export JAVA_HOME=`/usr/libexec/java_home -v 20`; java -version"
alias j19="export JAVA_HOME=`/usr/libexec/java_home -v 19`; java -version"
alias j18="export JAVA_HOME=`/usr/libexec/java_home -v 18`; java -version"
alias j17="export JAVA_HOME=`/usr/libexec/java_home -v 17`; java -version"
alias j16="export JAVA_HOME=`/usr/libexec/java_home -v 16`; java -version"
alias j15="export JAVA_HOME=`/usr/libexec/java_home -v 15`; java -version"
alias j14="export JAVA_HOME=`/usr/libexec/java_home -v 14`; java -version"
alias j13="export JAVA_HOME=`/usr/libexec/java_home -v 13`; java -version"
alias j12="export JAVA_HOME=`/usr/libexec/java_home -v 12`; java -version"
alias j11="export JAVA_HOME=`/usr/libexec/java_home -v 11`; java -version"
alias j10="export JAVA_HOME=`/usr/libexec/java_home -v 10`; java -version"
alias j9="export JAVA_HOME=`/usr/libexec/java_home -v 9`; java -version"
alias j8="export JAVA_HOME=`/usr/libexec/java_home -v 1.8`; java -version"
alias j7="export JAVA_HOME=`/usr/libexec/java_home -v 1.7`; java -version"

After inserting, execute $ source .bash_profile

I can switch to Java 8 by typing the following:

$ j8
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
9
  • 8
    This is the syntax for Java 9: alias j9="export JAVA_HOME=`/usr/libexec/java_home -v 9`; java -version"
    – elektromin
    Commented Oct 3, 2017 at 6:37
  • Using alias j10="export JAVA_HOME=`/usr/libexec/java_home`; java -version" and then typing j10 allows you to switch back to the current version of Java (in my case Java 10)
    – intagli
    Commented May 1, 2018 at 12:58
  • I would make a cli tool similar to nvm for switching Java versions, but the acronym jvm already means something else :)
    – Andy
    Commented Sep 22, 2018 at 18:48
  • I get this error when sourcing: /Users/me/.zshrc:8: permission denied: /Library/Java/JavaVirtualMachines/openjdk-12.jdk/Contents/Home
    – cosbor11
    Commented Apr 4, 2019 at 22:28
  • @cosbor11 for .zshrc use export JAVA_HOME=$(/usr/libexec/java_home -v 12)
    – oliolioli
    Commented Aug 22, 2019 at 12:12
72

Due to multiple Homebrew, cast(Deprecation Notice AdoptOpenJDK/openjdk), and MacOS updates I'm posting this updated answer.

Homebrew tap AdoptOpenJDK/openjdk is officially deprecated in favor of the temurin casks provided directly from the Homebrew project but Homebrew is the best way to manage and work with different Java versions.

In case you already have Homebrew and AdoptOpenJDK/openjdk cast installed, please untap this brew tap first:

$ brew untap AdoptOpenJDK/openjdk

if you do not have Homebrew installed.

1 - Install Homebrew.

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

2 - To download the latest Jave version (16):

$ brew install --cask temurin

3 - To install other versions:

$ brew tap homebrew/cask-versions
$ brew install --cask temurin8
$ brew install --cask temurin11
$ brew install --cask temurin17
$ brew install --cask temurin18
$ brew install --cask temurin19
$ brew install --cask temurin21

4 - Switch between different versions of Java

Switching between different versions of Java, you only need to add the following to your .bash_profile or .zshrc.

In this case, we want to be able to switch between Java8, Java11, Java17... and Java21:

export JAVA_8_HOME=$(/usr/libexec/java_home -v1.8)
export JAVA_11_HOME=$(/usr/libexec/java_home -v11)
export JAVA_17_HOME=$(/usr/libexec/java_home -v17)
export JAVA_18_HOME=$(/usr/libexec/java_home -v18)
export JAVA_19_HOME=$(/usr/libexec/java_home -v19)
export JAVA_21_HOME=$(/usr/libexec/java_home -v21)

alias java8='export JAVA_HOME=$JAVA_8_HOME'
alias java11='export JAVA_HOME=$JAVA_11_HOME'
alias java17='export JAVA_HOME=$JAVA_17_HOME'
alias java18='export JAVA_HOME=$JAVA_18_HOME'
alias java19='export JAVA_HOME=$JAVA_19_HOME'
alias java21='export JAVA_HOME=$JAVA_21_HOME'

# default to Java 21
java21

5 - Reload .bash_profile or .zshrc for the aliases to take effect:

$ source ~/.bash_profile

or

$ source ~/.zshrc

6 - Finally you can use the aliases to switch between different Java versions.

$ java8
$ java -version
java version "1.8.0_261"

Old Guide if you have old Homebrew and MacOS versions...

I will share my experiences with macOS Big Sur v11.4, the best way to deal with these problems is by installing Java using Homebrew:

1 - Install Homebrew.

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

2 - Install Homebrew Cask.

$ brew tap homebrew/cask-versions 
$ brew update 
$ brew tap homebrew/cask

3 - Install the latest version of Java

$ brew cask install java

4 - Install the other needed versions of Java (Java8, Java11, Java13).

$ brew tap adoptopenjdk/openjdk

$ brew cask install adoptopenjdk8
$ brew cask install adoptopenjdk11
$ brew cask install adoptopenjdk13
$ brew cask install adoptopenjdk14

5 - Switch between different versions of Java

Switching between different versions of Java, you only need to add the following to your .bash_profile or .zshrc.

In this case, we want to be able to switch between Java8, Java11, Java13 and Java14:

export JAVA_8_HOME=$(/usr/libexec/java_home -v1.8)
export JAVA_11_HOME=$(/usr/libexec/java_home -v11)
export JAVA_13_HOME=$(/usr/libexec/java_home -v13)
export JAVA_14_HOME=$(/usr/libexec/java_home -v14)

alias java8='export JAVA_HOME=$JAVA_8_HOME'
alias java11='export JAVA_HOME=$JAVA_11_HOME'
alias java13='export JAVA_HOME=$JAVA_13_HOME'
alias java14='export JAVA_HOME=$JAVA_14_HOME'

# default to Java 14
java14

6 - Reload .bash_profile or .zshrc for the aliases to take effect:

$ source ~/.bash_profile

or

$ source ~/.zshrc

7 - Finally you can use the aliases to switch between different Java versions.

$ java8
$ java -version
java version "1.8.0_261"

For more info, you can see this post: How to Use Brew to Install Java on Mac

6
  • Mind making a minor edit @hermeslm? Seeing this: brew tap caskroom/cask Error: caskroom/cask was moved. Tap homebrew/cask instead.
    – hafichuk
    Commented Sep 2, 2021 at 17:55
  • Good catch @hafichuk, this worked at the moment of this answer. I will edit it, thanks.
    – hermeslm
    Commented Sep 3, 2021 at 20:44
  • @hermeslm brew cask install won't work with newer versions, add an update of: brew install cask packageName. ReferenceL:stackoverflow.com/questions/30413621/… Commented Nov 25, 2021 at 10:23
  • I had to run brew install adoptopenjdk/openjdk/adoptopenjdk8 instead of brew cask install adoptopenjdk8
    – Vlad R
    Commented Feb 1, 2022 at 14:17
  • Nov 2022 update for Mac: export JAVA_11_HOME=/opt/homebrew/Cellar/openjdk@11/11.0.16.1/libexec/openjdk.jdk/Contents/Home export JAVA_17_HOME=/opt/homebrew/Cellar/openjdk@17/17.0.4.1/libexec/openjdk.jdk/Contents/Home export JAVA_18_HOME=/opt/homebrew/Cellar/openjdk/18.0.2.1/libexec/openjdk.jdk/Contents/Home alias java11='export JAVA_HOME=$JAVA_11_HOME' alias java17='export JAVA_HOME=$JAVA_17_HOME' alias java18='export JAVA_HOME=$JAVA_18_HOME' # default to Java 14 java18
    – lkahtz
    Commented Nov 23, 2022 at 7:02
67

A small fish function based on /usr/libexec/java_home

function jhome
    set JAVA_HOME (/usr/libexec/java_home $argv)
    echo "JAVA_HOME:" $JAVA_HOME
    echo "java -version:"
    java -version
end

If you don't use fish, you can do something similar in bash:

#!/bin/bash

jhome () {
  export JAVA_HOME=`/usr/libexec/java_home $@`
  echo "JAVA_HOME:" $JAVA_HOME
  echo "java -version:"
  java -version
}

Then to switch between javas do:

$> jhome           #switches to latest java
$> jhome -v 1.7    #switches to java 1.7
$> jhome -v 1.6    #switches to java 1.6

ref: https://gist.github.com/kenglxn/1843d552dff4d4233271

2
  • 2
    this only changes for the specific terminal session. Is there a way to update this to change it system wide?
    – ENG618
    Commented Mar 23, 2016 at 12:19
  • 1
    I had to write export JAVA_HOME=(/usr/libexec/java_home $argv) instead of the second line of your jhome function. Commented Sep 13, 2018 at 9:26
55

Use jenv is an easy way. (Update 2022)

  1. Install jenv: see Getting started

  2. Install java with brew

    brew install openjdk@11
    ln -s /usr/local/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk
    
    #other java
    brew install openjdk@8
    brew install openjdk@17
    
  3. Add java to jenv

    jenv add /Library/Java/JavaVirtualMachines/openjdk-11.jdk/Contents/Home
    
  4. Use: refer to jenv

6
  • Clean and nice solution.
    – pinturic
    Commented Jun 6, 2016 at 11:58
  • Instead of "jenv use java 1.8", I had to use "jenv shell 1.8". "shell" could also be "global" or "local" depending on the need. Commented Sep 9, 2016 at 14:44
  • 3
    jenv is nice when it works. Would recommend against it though, as it doesn't "really" change the default java version used, evident by running the command "/usr/libexec/java_home -V", only the JAVA_HOME. This causes weird problems with some applications, e.g. Eclipse.
    – simon
    Commented Jan 17, 2018 at 10:01
  • 1
    Besides that paranoidal part of me suggests against curling anything to bash. Even if you think the site is trusted no-one can guarantee you it's un-hackable. Use your OS' package manager. Commented Aug 7, 2018 at 9:43
  • That info is outdated. Check official documentation or more detailed instructions. Commented Dec 13, 2018 at 7:25
42

install JDK, not just JRE

/usr/libexec/java_home -v 1.8

gives

/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home

next

touch .bash_profile

open -a TextEdit.app .bash_profile

TextEdit will show you a blank page which you can fill in.

add to doc: export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home

in terminal:

export JAVA_HOME="$(/usr/libexec/java_home -v 1.8)"

try the command:

javac -version

should output:

javac 1.8.0_111
1
  • upvote for showing how to install JDK as well Commented Nov 1, 2022 at 13:25
41

It is a little bit tricky, but try to follow the steps described in Installing Java on OS X 10.9 (Mavericks). Basically, you gonna have to update your alias to java.

Step by step:

After installing JDK 1.7, you will need to do the sudo ln -snf in order to change the link to current java. To do so, open Terminal and issue the command:

sudo ln -nsf /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents \
/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK

Note that the directory jdk1.7.0_51.jdk may change depending on the SDK version you have installed.

Now, you need to set JAVA_HOME to point to where jdk_1.7.0_xx.jdk was installed. Open again the Terminal and type:

export JAVA_HOME="/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home"

You can add the export JAVA_HOME line above in your .bashrc file to have java permanently in your Terminal

10
  • 1
    how do i set JAVA_HOME Variable? is there a particular place I set it in?
    – Venkat
    Commented Feb 23, 2014 at 5:53
  • where am I exporting JAVA_HOME? and where will that be saved?
    – Venkat
    Commented Feb 23, 2014 at 5:59
  • 1
    I've updated the answer. Do you know the SDK version that you have installed? The folder name takes the SDK version number, so the commands above might change a bit.
    – Trein
    Commented Feb 23, 2014 at 5:59
  • I installed the latest one, I think it is 51.
    – Venkat
    Commented Feb 23, 2014 at 6:01
  • The variable JAVA_HOME will be exported on the current Terminal session. You can add it to our .bashrc if you want. I will adapt the commands to the last version.
    – Trein
    Commented Feb 23, 2014 at 6:02
34

tl;dr

Add the line:

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

to the file

~/.bash_profile

(replace jdk1.8.0_144.jdk with your downloaded version)

then source ~/.bash_profile

0
31

Use jenv, it is like a Java environment manager. It is super easy to use and clean

For Mac, follow the steps:

brew install jenv

git clone https://github.com/gcuisinier/jenv.git ~/.jenv

Installation: If you are using bash follow these steps:

$ echo 'export PATH="$HOME/.jenv/bin:$PATH"' >> ~/.bash_profile

echo 'eval "$(jenv init -)"' >> ~/.bash_profile

$ exec $SHELL -l

Add desired versions of JVM to jenv:

jenv add /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

jenv add /System/Library/Java/JavaVirtualMachines/1.8.0.jdk/Contents/Home

Check the installed versions:

jenv versions

Set the Java version you want to use by:

jenv global oracle64-1.6.0
1
  • I'm using a similar tool: sdkman.io/usage - IMHO much better approach than manual aliases etc
    – SathOkh
    Commented Apr 30, 2020 at 8:30
19

Consider the following approach only to change the JDK for each and specific tab of your terminal (i.e: iTerm).

Having in the /Library/Java/JavaVirtualMachines path the two following jdks

  • openjdk8u275-b01
  • openjdk-11.0.9.1+1

And in the .bash_profile file the following:

export JAVA_HOME=/Library/Java/JavaVirtualMachines/openjdk-11.0.9.1+1/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH

If you open Iterm - with the first Tab A - and the following commands are executed:

javac -version
javac 11.0.9.1

java -version
openjdk version "11.0.9.1" 2020-11-04
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.9.1+1)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.9.1+1, mixed mode)

The output is correct and expected

But if you open a second Tab B and you need override the default JDK then write in the terminal the following:

export JAVA_HOME=/Library/Java/JavaVirtualMachines/openjdk8u275-b01/Contents/Home/
export PATH=$JAVA_HOME/bin:$PATH

Then

javac -version
javac 1.8.0_275

java -version
openjdk version "1.8.0_275"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_275-b01)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.275-b01, mixed mode)

It works fine. Of course if the Tab B is closed or you open a new Tab C all work according the .bash_profile settings (therefore the default settings)

18

Run

/usr/libexec/java_home -V

you will get all the java version that you have

Example:-

Matching Java Virtual Machines (3):
    17.0.7 (x86_64) "Amazon.com Inc." - "Amazon Corretto 17" /Library/Java/JavaVirtualMachines/amazon-corretto-17.jdk/Contents/Home
    11.0.19 (x86_64) "Amazon.com Inc." - "Amazon Corretto 11" /Users/abhishek.khaiwale/Library/Java/JavaVirtualMachines/corretto-11.0.19/Contents/Home
    11.0.19 (x86_64) "Amazon.com Inc." - "Amazon Corretto 11" /Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home

If you need java version 11.0.19

Run

export JAVA_HOME=`/usr/libexec/java_home -v 11.0.19`

Youtube Video Link

2
  • This has already been mentioned in at least one of the other answers.
    – Eric Aya
    Commented Jul 27, 2023 at 9:25
  • @Eric Aya the answer had too many details to waste time in urgent situations. Commented Aug 2, 2023 at 7:15
17

Four easy steps using terminal for people who uses the default process.. :)

  1. echo $JAVA_HOME gives you current java home. For eg: /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/

  2. cd /Library/Java/JavaVirtualMachines/ will take you to the folder where u normally install jdks (It might be different for your machines)

  3. ls shows you available folders (normally it will have the version numbers, for eg: jdk1.8.0_191.jdk openjdk-11.0.2.jdk)
  4. export JAVA_HOME='/Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home' will change the java home..
16

macOS El Capitan or newer will choose the higher version of the JDK available in /Library/Java/JavaVirtualMachines, so in order to downgrade you may rename the file Info.plist to something else like Info.plist.disabled so that the OS will choose a previous version.

2
  • Easiest way to (: Thanks Commented Feb 10, 2020 at 11:28
  • This solution allows running VisualVM (currently not supporting JDK 16) with both JDK 15 and 16 installed.
    – pyb
    Commented Mar 22, 2021 at 16:42
13
function setjdk() {
  if [ $# -ne 0 ]; then
    removeFromPath '/System/Library/Frameworks/JavaVM.framework/Home/bin'
    if [ -n "${JAVA_HOME+x}" ]; then
      removeFromPath $JAVA_HOME
    fi
    export JAVA_HOME=`/usr/libexec/java_home -v $@`
    export PATH=$JAVA_HOME/bin:$PATH
  fi
}

put this in your ~/.profile and use it in your terminal like so setjdk 1.8, setjdk 1.7, setjdk 9 etc etc...

If you don't have removeFromPath then it is:

function removeFromPath() { export PATH=$(echo $PATH | sed -E -e "s;:$1;;" -e "s;$1:?;;") }

12

You can add it to your .bash_profile to have the version set by default.

//Open bash profile
open ~/.bash_profile

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

// run bash profile
source ~/.bash_profile
1
  • Thanks! Things of note, you must include the ` marks. and obviously, replace 1.8 with whatever version you might need. In my case 13.0.2
    – Jamie S
    Commented Mar 21, 2020 at 0:35
12

Add following in your ~/.bash_profile and set the default java version accordingly.

export JAVA_8_HOME=$(/usr/libexec/java_home -v1.8)
export JAVA_11_HOME=$(/usr/libexec/java_home -v11)

alias java8='export JAVA_HOME=$JAVA_8_HOME'
alias java11='export JAVA_HOME=$JAVA_11_HOME'

# default to Java 8
java8

I am using macOS and have installed java using brew.

Edit: If you are not using bash please update the correct shell file, example, if you are using zsh then it will be ~/.zshrc

4
  • so does it mean i should put in ~/.zprofile if I am using ~/.zshrc (or zsh terminal) Commented Nov 29, 2021 at 1:56
  • Updated the answer @elliotching
    – Vishrant
    Commented Dec 7, 2021 at 21:47
  • Beware -- if you do not have the flagged version installed, then java_home will return the default version (unless you include the -F flag). So this can be approach can be misleading!
    – Magnus
    Commented Jun 14, 2022 at 17:06
  • Not sure if I understand the concern, can you give an example? if someone is setting these variables in .bash_profile, then they are aware of the changes that are being done, it does not happen automatically.
    – Vishrant
    Commented Jun 14, 2022 at 18:15
10

add following command to the ~/.zshenv file

export JAVA_HOME=`/usr/libexec/java_home -v 1.8` 
0
8
  1. Add the following line of code to your .zshrc (or bash_profile):

alias j='f(){ export JAVA_HOME=/usr/libexec/java_home -v $1 };f'

  1. Save to session:

$ source .zshrc

  1. Run command (e.g. j 13, j14, j1.8...)

$ j 1.8

Explanation This is parameterised so you do not need to update the script like other solutions posted. If you do not have the JVM installed you are told. Sample cases below:

/Users/user/IDE/project $ j 1.8
/Users/user/IDE/project $ java -version
openjdk version "1.8.0_265"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_265-b01)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.265-b01, mixed mode)
/Users/user/IDE/project $ j 13
/Users/user/IDE/project $ java -version
openjdk version "13.0.2" 2020-01-14
OpenJDK Runtime Environment (build 13.0.2+8)
OpenJDK 64-Bit Server VM (build 13.0.2+8, mixed mode, sharing)
/Users/user/IDE/project $ j 1.7
Unable to find any JVMs matching version "1.7".
1
  • 1
    after I add the script to .zshrc, then run it like j 11, the terminal outputs: f:export: not valid in this context: -v
    – Dika
    Commented Apr 1, 2022 at 2:01
8

Check Java version: java -version

Switch between versions: https://devqa.io/brew-install-java/

open ~/.bash_profile

export JAVA_8_HOME=$(/usr/libexec/java_home -v1.8)

export JAVA_11_HOME=$(/usr/libexec/java_home -v11)

alias java8='export JAVA_HOME=$JAVA_8_HOME' alias java11='export JAVA_HOME=$JAVA_11_HOME'

source ~/.bash_profile

When we are switching to java11 or java8, java -version command is not showing the correct version.

In that case use mvn -version to see the correct java version is used for building the solution

7

From the Apple's official java_home(1) man page:

**USAGE**

   /usr/libexec/java_home  helps  users  set a $JAVA_HOME in their login rc files, or provides a way for
   command-line Java tools to use the most appropriate JVM which can satisfy a minimum version or archi-
   tecture  requirement.  The --exec argument can invoke tools in the selected $JAVA_HOME/bin directory,
   which is useful for starting Java command-line tools from launchd plists without hardcoding the  full
   path to the Java command-line tool.

   Usage for bash-style shells:
          $ export JAVA_HOME=`/usr/libexec/java_home`

   Usage for csh-style shells:
          % setenv JAVA_HOME `/usr/libexec/java_home`
7

JDK Switch Script

I have adapted the answer from @Alex above and wrote the following to fix the code for Java 9.

$ cat ~/.jdk
#!/bin/bash

#list available jdks
alias jdks="/usr/libexec/java_home -V"
# jdk version switching - e.g. `jdk 6` will switch to version 1.6
function jdk() {
  echo "Switching java version $1";

  requestedVersion=$1
  oldStyleVersion=8
  # Set the version
  if [ $requestedVersion -gt $oldStyleVersion ]; then
    export JAVA_HOME=$(/usr/libexec/java_home -v $1);
  else
    export JAVA_HOME=`/usr/libexec/java_home -v 1.$1`;
  fi

  echo "Setting JAVA_HOME=$JAVA_HOME"

  which java
  java -version;
}

Switch to Java 8

$ jdk 8
Switching java version 8
Setting JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home
/usr/bin/java
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

Switch to Java 9

$ jdk 9
Switching java version 9
Setting JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home
/usr/bin/java
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)
7

With no additional tools to install, an easy way to have a separately installed JDK recognized as a first class member by /usr/libexec/java_home -V is to symlink it as follows:

sudo ln -s <path> /Library/Java/JavaVirtualMachines/jdk-[some-identifier].jdk

<path> is expected to be a directory containing subdirectories Contents/Home/bin etc.


A common use case is to register the JDK/JRE included with Android Studio:

The default location for the Java tools in recent versions of Android Studio on macOS is /Applications/Android\ Studio.app/Contents/jre. We will use jdk-android-studio.jdk as the identifier:

sudo ln -s /Applications/Android\ Studio.app/Contents/jre /Library/Java/JavaVirtualMachines/jdk-android-studio.jdk

Now, /usr/libexec/java_home -V will list it under Matching Java Virtual Machines:

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (1):
    11.0.13 (arm64) "JetBrains s.r.o." - "OpenJDK 11.0.13" /Applications/Android Studio.app/Contents/jre/Contents/Home
/Applications/Android Studio.app/Contents/jre/Contents/Home
2
  • 1
    this helped me in a second to solve issue in KMM "project Command PhaseScriptExecution failed with a nonzero exit code"
    – micdev
    Commented Dec 13, 2022 at 12:30
  • this doesn't work in Sonoma 14.5. Info.plist is needed as per this answer stackoverflow.com/a/76523554/1731475 Commented Jun 3 at 15:53
6

If still u are not able to set it. using this command.

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

then you have to use this one.

export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)

it will surely work.

6

First find out where do you store the environment variables-

  1. emacs
  2. bash_profile
  3. zshrc file

Steps to Set up the environment variable :-

  1. Download the jdk from JAVA

  2. install it by double click

  3. Now set-up environment variables in your file

    a. For emacs.profile you can use this link OR see the screenshot below

enter image description here

b. For ZSH profile setup -

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

2. source ~/.zshrc - Restart zshrc to reflect the changes.

3. echo $JAVA_HOME - make sure path is set up properly 
   ----> /Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home

4. java -version 

   -->  java version "1.8.0_112"  Java(TM) SE Runtime Environment (build 1.8.0_112-b16)Java HotSpot(TM) 64-Bit Server VM (build 25.112-b16, mixed mode)

All set Now you can easily upgrade or degrade the JAVA version..

6

Previously I used alias'es in .zshrc for easy switching between versions but today I use SDKMAN. SDKMAN can also handle setting default java for the system, and downloading and installing new java versions.

Once sdkman is installed you can then do commands similar to what is possible with the nvm tool for handling node versions.

sdk list java will list the java versions available on your system as well as available online for installation including their identifier that you can use in the sdk use, sdk default and sdk install commands.

e.g. to install Amazon Corretto 11.0.8 and ask if it should be the new default do this: sdk install java 11.0.8-amzn

A feature I also use regularly is the .sdkmanrc file. If you place that in a directory on your machine and run the sdk env command in the directory then you can configure tool versions used only in that directory. It is also possible to make sdkman switch tool versions automatically using the sdkman_auto_env=true configuration.

sdkman also supports handling other tools for the JVM such as gradle, kotlin, maven and more.

For more information check out https://sdkman.io/usage#env

4

If you are using fish and you are using mac and you want to be able to switch between JDK's, then below works for me on mac.

@kenglxn's answer didn't work for me and I figured out it bcos didn't set -g which is global !

Put below under ~/.config/fish/config.fish

alias j8="jhome  -v 1.8.0_162"
alias j9="jhome  -v 9.0.1"

function jhome
    set -g -x JAVA_HOME (/usr/libexec/java_home $argv)
    echo "JAVA_HOME:" $JAVA_HOME
    echo "java -version:"
    java -version
end

funcsave jhome

To know which version /minor version you have installed, you can do :

/usr/libexec/java_home -V                                                                              579ms  Wed 14 Feb 11:44:01 2018
Matching Java Virtual Machines (3):
    9.0.1, x86_64:  "Java SE 9.0.1" /Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home
    1.8.0_162, x86_64:  "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home
    1.8.0_121, x86_64:  "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
3

If you have multiple versions and you want to run something by using a specific version, use this example:

/usr/libexec/java_home -v 1.7.0_75 --exec java -jar you-file.jar
0
2

Based on @markhellewell answer I created a couple of alias functions that will do it for you. Just add these to your shell startup file

#list available jdks
alias jdks="/usr/libexec/java_home -V"
# jdk version switching - e.g. `jdk 6` will switch to version 1.6
function jdk() { 
  echo "Switching java version"; 
  export JAVA_HOME=`/usr/libexec/java_home -v 1.$1`; 
  java -version; 
}

https://gist.github.com/Noyabronok/0a90e1f3c52d1aaa941013d3caa8d0e4

2

Here is how I do it on my Linux (Ubuntu / Mint mate), I guess Mac can do it similarly.


Install & config

Steps:

  • [Basic - part]
  • Download jdk (the .tgz file) by hand.
  • Uncompress & rename properly, at a proper location.
    e.g /mnt/star/program/java/jdk-1.8
  • Make a soft link, which will be changed to switch java version later.
    e.g ln -s /mnt/star/program/java/jdk-1.8 /mnt/star/program/java/java
    Thus /mnt/star/program/java/java is the soft link.
  • Set JAVA_HOME in a start script.
    Could use file like /etc/profile.d/eric.sh, or just use ~/.bashrc.
    e.g JAVA_HOME=/mnt/star/program/java/java
  • Then open a new bash shell. java -version should print the java version.
  • [More version - part]
  • Download & install more Java version, as need, similar as above steps.
    e.g
    /mnt/star/program/java/jdk-11
  • [Switch - part]
  • In ~/.bashrc, define variable for various Java version.
    e.g
    _E_JAVA_HOME_11='/mnt/star/program/java/jdk-11'
    _E_JAVA_HOME_8='/mnt/star/program/java/jdk-8'
    # dir of default version,
    _E_JAVA_HOME_D=$_E_JAVA_HOME_8
  • In ~/.bashrc, define command to switch Java version.
    e.g
    ## switch java version,
    alias jv11="rm $JAVA_HOME; ln -s $_E_JAVA_HOME_11 $JAVA_HOME"
    alias jv8="rm $JAVA_HOME; ln -s $_E_JAVA_HOME_8 $JAVA_HOME"
    # default java version,
    alias jvd="rm $JAVA_HOME; ln -s $_E_JAVA_HOME_D $JAVA_HOME"
    alias jv="java -version"
  • In terminal, source ~/.bashrc to make the changes take effect.
  • Then could switch using the defined commands.

Commands - from above config

Commands:

  • jv11
    Switch to Java 11
  • jv8
    Switch to Java 8
  • jvd
    Switch to default Java version, which is denoted by _E_JAVA_HOME_D defined above.
  • jv
    Show java version.

Example output:

eric@eric-pc:~$ jv
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)

eric@eric-pc:~$ jv11
eric@eric-pc:~$ jv
java version "11.0.1" 2018-10-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.1+13-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.1+13-LTS, mixed mode)

eric@eric-pc:~$ jvd
eric@eric-pc:~$ jv
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)

eric@eric-pc:~$ 

Mechanism

  • It switch by changing the soft link, which is used as JAVA_HOME.

Tips

  • On my machine when install jdk by hand, I keep the minor version, then make a soft link with the major version but without the minor version.
    e.g
    // this is the actual dir,
    jdk1.8.0_191

    // this is a soft link to jdk1.8.0_191
    jdk-8

    // this is a soft link to jdk-8 or jdk-11
    java

  • I define command alias in ~/.bashrc, but define variable in a separate file.
    I am using ~/.eric_var to define the variables, and ~/.bashrc will source it (e.g source $HOME/.eric_var).

Not the answer you're looking for? Browse other questions tagged or ask your own question.