How to switch JDK version on Mac OS X

Apple decided to remove the Java Preferences application in a software update and afterwards in has been difficult to change the JDK version on Mac OS X. I especially noticed this after I installed the JDK 8 early access preview which makes some of the tips that you find on various blogs online useless. After a lot of googling I finally found a simple solution that I’d like to share.

What you do is to edit your ~/.bash_profile and add the following:

What the script does is to first remove other JDK versions in the PATH so that they won’t interfere with our new JDK version. Then it makes some clever use of /usr/libexec/java_home which is a command that lists installed JDK versions. The -v argument tells java_home to return the path of the JDK with the supplied version, for example 1.7. We also update the PATH to point to the bin directory of the newly found JAVA_HOME directory. At the end we can simply execute the function using

which selects the latest installed JDK version of the 1.7 branch. To select a specific version you can simply execute

instead. Run /usr/libexec/java_home -h to get more details on how to choose versions.

That’s it! All credits should go to Neeme Praks and his answer on superuser.com.

This Post Has 63 Comments

  1. Thanx for the script. Worked well for me.

  2. Thanks man!

    I was running something like export JAVA_HOME=java_home -v 1.6, but the scripts also takes care of the PATH so it’s definitively more convenient.

    For those which, like in my case, don’t have ~/.bash_profile, you can also add it like an script under /usr/local/bin

  3. Many thanks!

    Works really great for Java up to version 1.8

  4. Thank you very much for yet another very elegant solution to an annoying problem!

  5. Works well but borks on the removeFromPath function when your Path contains a folder that contains spaces, for example “/Applications/Flash Player Debugger.app”.

  6. Thank you so much!

  7. Great. Works perfectly well and solve a really annoying issue :)

  8. Thank you thank you, this saved my butt! I can’t believe Apple removed feature to change it trivially though :(

  9. I’m getting this message in terminal after adding you code to .bash_profile

    Unable to find any JVMs matching version “1.7”.

    1. And you’re sure that you have Java 7 installed?

  10. This works for applications, but not for applets. I need my Firefox to use Java 1.7 plugin, but after running your script FIrefox still has Java 1.8 plugin and so far I don’t know how to make it switch to Java 1.7.

    Thanks for the script anyway!

  11. Thanks for this! Most helpful in managing multiple JDK versions.

  12. This should be added to .bash_profile as part of JDK installation.
    Or perhaps burnt into an EPROM on every new Mac sold.

    Anyways, thank you for making my day suck a lot less !

  13. Life saver!

  14. Super simple and straight forward! Thank you so much!

  15. Great! Well-explained and just what I was looking for.

  16. Time saver ! Thanks for sharing this.

  17. Thank you Johan, the script works perfectly !!

  18. I refined the script just a little bit to be able to choose from the existing versions, which saves entering the java_home -V:

    function setjdk() {
    if [ $# -ne 0 ]; then
    switchjdk $@
    else
    echo “Choose from the following Java versions:”
    choosejdk
    echo “Please enter the correct full version number:”
    read jdkPick
    switchjdk $jdkPick
    fi
    }

    function switchjdk() {
    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
    }

    function choosejdk() {
    allVersions=$(/usr/libexec/java_home -V)
    }

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

  19. Thanks for this. Really helpful

  20. Works – nice, thanks.

  21. SO awesome! Thanks for reposting this.

  22. This will work as well, and is relatively robust assuming ‘tr’ and ‘sed’ behave nicely (uses bash):

  23. I think JEnv (http://www.jenv.be/) solves the problem nicely, with added bonus of customizing java version for each directory.

    1. Thanks for the tip, seems very useful.

  24. Thanks! Works like a charm.

  25. This was AWESOME. Thanks!

  26. Thanks for this function, really useful !

    However, I have a question : I need 2 versions (jdk 1.8 for maven and 1.7 for jboss).
    To switch between my 2 servers, I have to add or remove your function. Is there a solution to do have something who recognize automatically which version I need ? To avoid editing each time the bash profile ?
    Thanks in advance !

  27. Thank you tons!!!

  28. I think that line 5 should be: “removeFromPath $JAVA_HOME/bin”; otherwise, it leaves behind a stray “/bin:” each time you use setjdk. Except for that, it works great! I only noticed it because I changed the PATH after the call to setjdk and that borked the directory that I’d added.

  29. THANKS – great help!!!

  30. Thanks. I’m using it with latest version of 1.8.

  31. Great this script is working for me.

  32. Very nice. Thanks.

  33. Awesome, awesome, awesome and awesome. Thanks for a great script!

  34. very nice

  35. Just want to thank you for this very useful tip !
    Works great when switching between 7u60 and 8u40

  36. Rocking!!!

    Thank you buddy.

  37. I noticed that the removeFromPath was leaving the trailing /bin in the PATH. I corrected it (and made it pass shellcheck linter).



    #!/bin/bash

    #From http://blog.jayway.com/2014/01/15/how-to-switch-jdk-version-on-mac-os-x-maverick/
    function setjdk() {
    if [ $# -ne 0 ]; then
    removeFromPath '/System/Library/Frameworks/JavaVM.framework/Home/bin'
    #Bash expansion will be "x" if JAVA_HOME set, emptystring if unset
    #http://wiki.bash-hackers.org/syntax/pe#use_an_alternate_value
    if [ -n "${JAVA_HOME+x}" ]; then
    removeJavaFromPath "${JAVA_HOME}/bin"
    fi
    export JAVA_HOME=$(/usr/libexec/java_home -v "$@")
    export PATH=$JAVA_HOME/bin:$PATH
    fi
    }
    function removeJavaFromPath() {
    export PATH="$(echo "$PATH" | sed -E -e "s;:$1;;" -e "s;$1:?;;")"
    }

  38. There is a different answer in the SuperUser question you linked with more upvotes. I ended up going for that solution – perhaps consider updating your article if you also like that solution better as your article was the top hit on google for me :)

  39. That was superb!!! thanks a lot for solving an annoying problem

  40. I’m getting this error when I ran the file:

    Babatundes-iMac:~ tfalade$ source ~/.bash_profile
    -bash: /Users/tfalade/.bash_profile: line 3: syntax error near unexpected token then'
    -bash: /Users/tfalade/.bash_profile: line 3:
      if [ $# -ne 0 ]; then’

    Is there something that I’m doing wrong?

  41. I’m getting this error when I ran the function:
    Babatundes-iMac:~ tfalade$ source ~/.bash_profile
    -bash: /Users/tfalade/.bash_profile: line 3: syntax error near unexpected token then'
    -bash: /Users/tfalade/.bash_profile: line 3:
      if[ $# -ne 0 ]; then’

    Please help

  42. Awesome, works like a charm! I forgot about changing the PATH, I typically just jet JAVA_HOME, but that stopped working recently (in some cases), since there very symlinks like /usr/bin/java ->

  43. Thanks for the script. Works as it is described!

  44. Many thanks. Works a treat!!

  45. Thanks ! Work great !

  46. Thanks for this, it work for me.
    Just setjdk 1.7 should not include in script

  47. thnx a lot.

  48. Working great in 2018 on Sierra!

Leave a Reply

Close Menu