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 |
Output for
min=1.6
max=1.7.0_41
on my current system:
Found:
9.0.1:/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java
9:/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/bin/java
1.8.0_144:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java
1.7.0_79:/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java
9.0.1:/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java
Matching:
Sorted:
Highest:
doesn't match no JVM installed on my system cause I don't have Java 6 and 1.7.0_41
is lower than my installed JDK 1.7.0_79
Output for
min=9
max=
on my current system:
Found:
9.0.1:/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java
9:/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/bin/java
1.8.0_144:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java
1.7.0_79:/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java
9.0.1:/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java
Matching:
09000001:9.0.1:/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java
09000000:9:/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/bin/java
09000001:9.0.1:/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java
Sorted:
09000001:9.0.1:/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java
09000001:9.0.1:/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java
09000000:9:/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/bin/java
Highest:
/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java
09000001
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)
matches all the Java 9 versions because no max
version is required
Output for
min=1.7.0_79
max=1.8.0_144
on my current system:
Found:
9.0.1:/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java
9:/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/bin/java
1.8.0_144:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java
1.7.0_79:/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java
9.0.1:/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java
Matching:
08000144:1.8.0_144:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java
07000079:1.7.0_79:/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java
Sorted:
08000144:1.8.0_144:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java
07000079:1.7.0_79:/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java
Highest:
/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java
08000144
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
matches my JDK 7 and JDK 8.
Note that max
is interpreted as lower or equal than $max
!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output for
on my current system:
picks Java 1.8.0_144 because
max=1.8
selects all Java 1.8 versions.