DEV Community

Nikos Katsanos
Nikos Katsanos

Posted on

5 2

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

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

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

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

AWS GenAI Live!

GenAI LIVE! is a dynamic live-streamed show exploring how AWS and our partners are helping organizations unlock real value with generative AI.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️