DEV Community

Nikos Katsanos
Nikos Katsanos

Posted on

Managing JDKs in MacOS

With the increasing number of JDK builds and the more frequent release cadence, I found it hard to keep track what I had installed in my MacOS and switch between them on the fly.

Even in 2020 my preferred version of Java is 1.8(although I am trying to make use of Java 14 as much as possible), probably because this is the version I am using at my work. But depending on the occasion I find myself experimenting with newer features from later versions, or even from experimental builds:

  • JShell from Java 9 onwards
  • EpsilonGC
  • The use of var since Java 10
  • Value types in Project Valhalla builds
  • ZGC (the key feature I want to start making use of Java14)
  • etc…

In addition, nowadays on my personal computer I mainly use Java builds from the AdoptOpenJDK project. But there are other builds which I have installed on my MacOS to try out:

Hence I spent some putting together some bash functions that give me a hand managing and switching between those versions on the fly.

For the complete bash script see here, but the highlights are:

List JKDs

function listJDKs() { echo "$($java_home -V 2>&1)" } 

Output

[:~]$listJDKs Matching Java Virtual Machines (5): 14, x86_64: "AdoptOpenJDK 14" /Library/Java/JavaVirtualMachines/adoptopenjdk-14.jdk/Contents/Home 13.0.2, x86_64: "AdoptOpenJDK 13" /Library/Java/JavaVirtualMachines/adoptopenjdk-13.jdk/Contents/Home 1.8.0_222, x86_64: "AdoptOpenJDK 8" /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home 1.8.0_212, x86_64: "GraalVM CE 19.0.0" /Library/Java/JavaVirtualMachines/graalvm-ce-19.0.0/Contents/Home 1.8.0_163-zulu-8.28.0.1, x86_64: "Zulu 8" /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home 

List Different JDK builds

function listJDKVendors() { echo "$($java_home -V 2>&1 | tr ' ' '\0' | tr '\t' ' ' | cut -d ' ' -f2,1)" } 

Output

[:~]$listJDKVendors MatchingJavaVirtualMachines(5): 14,x86_64: "AdoptOpenJDK14" 13.0.2,x86_64: "AdoptOpenJDK13" 1.8.0_222,x86_64: "AdoptOpenJDK8" 1.8.0_212,x86_64: "GraalVMCE19.0.0" 1.8.0_163-zulu-8.28.0.1,x86_64: "Zulu8" 

Set JDK to a specific version/vendor

function setJDK() { local USAGE="Usage: setJDK [-v \${JDK_VERSION}] [-d \${JDK_DISTRIBUTION}]" local OPTIND v d while getopts "v:d:" OPTION; do case "$OPTION" in v) local version=$OPTARG ;; d) local dist=$OPTARG ;; ?) echo $USAGE return 1 ;; esac done if [ $# -lt 1 ]; then echo $USAGE return 1 fi if [ -n "$version" ] && [ "$dist" ]; then echo "Setting JAVA to version $version and distribution $dist" local versionAndDistNo=$($java_home -V 2>&1 | grep $dist | grep $version | wc -l) if [ "$versionAndDistNo" -gt 1 ];then echo "Multiple JAVA versions found for arguments -v $version -d $dist . Unable to setJDK" listJDKs return 1 else export JAVA_HOME=$($java_home -V 2>&1 | grep $dist | grep $version | tr ' ' '\0' | tr '\t' ' ' | cut -d ' ' -f 3) fi elif [ -n "$dist" ]; then echo "Setting JAVA to distribution $dist" local distNo=$($java_home -V 2>&1 | grep $dist | wc -l) if [ $distNo -gt 1 ];then echo "Multiple versions for $dist. Unable to setJDK" listJDKs return 1 else export JAVA_HOME=$($java_home -V 2>&1 | grep $dist | tr ' ' '\0' | tr '\t' ' ' | cut -d ' ' -f 3) fi elif [ -n "$version" ]; then echo "Setting JAVA to version $version" export JAVA_HOME=$($java_home -v $version) else echo $USAGE fi echo "JAVA_HOME=${JAVA_HOME}" return 0 } 

Output

[:~]setJDK -v 14 Setting JAVA to version 14 JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-14.jdk/Contents/Home 

Note that java_home=/usr/libexec/java_home

Top comments (5)

Collapse
 
philippsuntz profile image
philippsuntz

Hi Nikos,

nice article. I had to same, needing to change my JDK for multiple projects with a new developed and a legacy code base. For me i found sdkman very helpful (sdkman.io/).
It dose the same job as your script + it allows you to download additional JDKs if needed. Also tools like gradle can be managed with it and maintained in multiple versions.

Collapse
 
nikos_katsanos profile image
Nikos Katsanos

Hey Philip, Thank you for the suggestion. Didn't know about that, but it looks pretty cool and promising. Will give it a go. I definitely prefer something that is supported by many people :)

Collapse
 
shostarsson profile image
Rémi Lavedrine

Hi Nikos,

I encountered this problem using an SDK for iOS application obfuscation.
I used jenv and it works pretty well.

Collapse
 
nikos_katsanos profile image
Nikos Katsanos

Hello Rèmi, thank you for suggesting. Seems like managing JDKs in a Mac/Dev machine is a general concern. jevn looks promising as well. Pretty sure this and http:// sdkman.io as suggested above will be much better than my hacky scripts :)

Collapse
 
shostarsson profile image
Rémi Lavedrine

I explained how I made it in that Post :

It is basically :

brew install jenv echo 'export PATH="$HOME/.jenv/bin:$PATH"' >> ~/.bash_profile echo 'eval "$(jenv init -)"' >> ~/.bash_profile source ~/.bash_profile