Last active
January 29, 2018 23:19
-
-
Save tofi86/3d5973f8cb259f07207451d051a52ae1 to your computer and use it in GitHub Desktop.
Find a suitable Java Virtual Machine on Mac OS X which matches a min/max version requirement
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
function get_java_version_from_cmd() { | |
# second sed command strips " and -ea from the version string | |
echo $("$1" -version 2>&1 | awk '/version/{print $NF}' | sed -E 's/"//g;s/-ea//g') | |
} | |
function get_comparable_java_version() { | |
# cleaning: 1) remove leading '1.'; 2) remove 'a-Z' and '-*+' (e.g. '-ea'); 3) replace '_' with '.' | |
local cleaned=$(echo "$1" | sed -E 's/^1\.//g;s/[a-zA-Z+*\-]//g;s/_/./g') | |
# splitting at '.' into an array | |
local arr=( ${cleaned//./ } ) | |
# echo a string with left padded version numbers | |
echo "$(printf '%02s' ${arr[0]})$(printf '%03s' ${arr[1]})$(printf '%03s' ${arr[2]})" | |
} | |
min=1.8 | |
minC=$(get_comparable_java_version $min) | |
max=9 | |
maxC=$(get_comparable_java_version $max) | |
# default Apple JRE plugin path | |
apple_jre_plugin="/Library/Java/Home/bin/java" | |
apple_jre_version=$(get_java_version_from_cmd "${apple_jre_plugin}") | |
# default Oracle JRE plugin path | |
oracle_jre_plugin="/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java" | |
oracle_jre_version=$(get_java_version_from_cmd "${oracle_jre_plugin}") | |
######################################## | |
# find installed JavaVirtualMachines (JDK + JRE) | |
############################################ | |
allJVMs=() | |
# read JDK's from '/usr/libexec/java_home -V' command | |
while read line; do | |
version=$(echo $line | awk -F $',' '{print $1;}') | |
path=$(echo $line | awk -F $'" ' '{print $2;}') | |
path+="/bin/java" | |
allJVMs+=("$version:$path") | |
done < <(/usr/libexec/java_home -V 2>&1 | grep '^[[:space:]]') | |
# unset while loop variables | |
unset version path | |
# add Apple JRE if available | |
if [ -x "${apple_jre_plugin}" ] ; then | |
allJVMs+=("$apple_jre_version:$apple_jre_plugin") | |
fi | |
# add Oracle JRE if available | |
if [ -x "${oracle_jre_plugin}" ] ; then | |
allJVMs+=("$oracle_jre_version:$oracle_jre_plugin") | |
fi | |
# debug output | |
echo "" | |
echo "Found:" | |
for i in "${allJVMs[@]}" | |
do | |
echo $i | |
done | |
# determine JVMs matching the min/max version requirement | |
############################################ | |
matchingJVMs=() | |
for i in "${allJVMs[@]}" | |
do | |
# split JVM string at ':' delimiter to retain spaces in $path substring | |
IFS=: arr=($i) ; unset IFS | |
# [0] JVM version number | |
ver=${arr[0]} | |
# comparable JVM version number | |
comp=$(get_comparable_java_version $ver) | |
# [1] JVM path | |
path="${arr[1]}" | |
# construct string item for adding to the "matchingJVMs" array | |
item="$comp:$ver:$path" | |
# pre-requisite: current version number needs to be greater than min version number | |
if [ "$comp" -ge "$minC" ] ; then | |
# perform max version checks if max version requirement is present | |
if [ ! -z ${max} ] ; then | |
# max version requirement ends with '*' modifier | |
if [[ ${max} == *\* ]] ; then | |
# use the '*' modifier from the max version string as wildcard for a 'starts with' comparison | |
# and check whether the current version number starts with the max version wildcard string | |
if [[ ${ver} == ${max} ]]; then | |
matchingJVMs+=("$item") | |
# or whether the current comparable version is lower than the comparable max version | |
elif [ "$comp" -le "$maxC" ] ; then | |
matchingJVMs+=("$item") | |
fi | |
# max version requirement ends with '+' modifier -> always add this version if it's greater than $min | |
# because a max requirement with + modifier doesn't make sense | |
elif [[ ${max} == *+ ]] ; then | |
matchingJVMs+=("$item") | |
# matches 6 zeros at the end of the max version string (e.g. for 1.8, 9) | |
# -> then the max version string should be treated like with a '*' modifier at the end | |
#elif [[ ${maxC} =~ ^[0-9]{2}0{6}$ ]] && [ "$comp" -le $(( ${maxC#0} + 999 )) ] ; then | |
# matchingJVMs+=("$item") | |
# matches 3 zeros at the end of the max version string (e.g. for 9.1, 10.3) | |
# -> then the max version string should be treated like with a '*' modifier at the end | |
#elif [[ ${maxC} =~ ^[0-9]{5}0{3}$ ]] && [ "$comp" -le "${maxC}" ] ; then | |
# matchingJVMs+=("$item") | |
# matches standard requirements without modifier | |
elif [ "$comp" -le "$maxC" ]; then | |
matchingJVMs+=("$item") | |
fi | |
# no max version requirement -> add current version to matching list | |
else | |
matchingJVMs+=("$item") | |
fi | |
fi | |
done | |
# unset for loop variables | |
unset arr ver comp path item | |
# debug output | |
echo "" | |
echo "Matching:" | |
for i in "${matchingJVMs[@]}" | |
do | |
echo $i | |
done | |
# sort the matching JavaVirtualMachines by version number | |
############################################ | |
# https://stackoverflow.com/a/11789688/1128689 | |
IFS=$'\n' matchingJVMs=($(sort -nr <<<"${matchingJVMs[*]}")) | |
unset IFS | |
# debug output | |
echo "" | |
echo "Sorted:" | |
for i in "${matchingJVMs[@]}" | |
do | |
echo $i | |
done | |
# get the highest matching JVM | |
############################################ | |
JAVACMD= | |
JAVACMD_version= | |
for ((i = 0; i < ${#matchingJVMs[@]}; i++)); | |
do | |
# split JVM string at ':' delimiter to retain spaces in $path substring | |
IFS=: arr=(${matchingJVMs[$i]}) ; unset IFS | |
# [0] comparable JVM version number | |
comp=${arr[0]} | |
# [1] JVM version number | |
ver=${arr[1]} | |
# [2] JVM path | |
path="${arr[2]}" | |
# use current value as JAVACMD if it's executable | |
if [ -x "$path" ] ; then | |
JAVACMD="$path" | |
JAVACMD_version=$comp | |
break | |
fi | |
done | |
# unset for loop variables | |
unset arr comp ver path | |
# debug output | |
echo "" | |
echo "Highest:" | |
echo $JAVACMD | |
echo $JAVACMD_version | |
if [ -x "$JAVACMD" ] ; then | |
echo $("${JAVACMD}" -version) | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output for
on my current system:
matches my JDK 7 and JDK 8.
Note that
max
is interpreted aslower or equal than $max
!