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)
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.
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 :)
Hi Nikos,
I encountered this problem using an SDK for iOS application obfuscation.
I used jenv and it works pretty well.
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 :)I explained how I made it in that Post :
Application Obfuscation on iOS
Rémi Lavedrine ・ Jun 27 '19 ・ 7 min read
It is basically :