Upgrades java.sh to be more thorough and respect already configured environments.

This commit is contained in:
2026-09-07 18:01:26 -07:00
parent 094d3f97ee
commit 2e309ce15f

View File

@@ -1,18 +1,159 @@
# TODO: Use find to get subdirs. Filter by vendor. Filter by version. Find the "best" version/vendor combo. # Setup Java environment (JAVA_HOME, JDK_HOME, and PATH)
# Highest microsoft version, if not fallback to highest non-ms version _setup_java() {
# Brew has graalvm (17,21), microsoft (11,17,21), oracle(17,21), sapmachine, semeru (8,11,17,21) [ -n "$ZSH_VERSION" ] && setopt localoptions nonomatch nullglob
if [ -z "${JAVA_HOME}" -a -d "/Library/Java/JavaVirtualMachines/microsoft-21.jdk/Contents/Home" ]; then
JAVA_HOME=/Library/Java/JavaVirtualMachines/microsoft-21.jdk/Contents/Home
elif [ -z "${JAVA_HOME}" -a -d "/Library/Java/JavaVirtualMachines/microsoft-17.jdk/Contents/Home" ]; then
JAVA_HOME=/Library/Java/JavaVirtualMachines/microsoft-17.jdk/Contents/Home
elif [ -z "${JAVA_HOME}" -a -d "/Library/Java/JavaVirtualMachines/microsoft-11.jdk/Contents/Home" ]; then
JAVA_HOME=/Library/Java/JavaVirtualMachines/microsoft-11.jdk/Contents/Home
elif [ -z "${JAVA_HOME}" -a -d "/Applications/Android\ Studio.app/Contents/jre/jdk/Contents/Home" ]; then
JAVA_HOME=/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home
fi
if [ -n "$JAVA_HOME" ]; then _is_valid_jre() {
path=("$JAVA_HOME/bin" $path) [ -n "$1" ] && [ -d "$1" ] && [ -x "$1/bin/java" ]
export JAVA_HOME }
export PATH
fi _is_valid_jdk() {
_is_valid_jre "$1" && [ -x "$1/bin/javac" ]
}
_add_to_path() {
[ -d "$1" ] || return 0
case ":$PATH:" in
*":$1:"*) ;;
*) PATH="$1:$PATH"; export PATH ;;
esac
}
# 1. If user already has a valid JAVA_HOME configured, respect it
_has_user_jre=0
if _is_valid_jre "${JAVA_HOME:-}"; then
_has_user_jre=1
_add_to_path "$JAVA_HOME/bin"
if _is_valid_jdk "$JAVA_HOME"; then
[ -z "$JDK_HOME" ] && export JDK_HOME="$JAVA_HOME"
fi
fi
# If both a valid JRE (JAVA_HOME) and JDK (JDK_HOME) are already configured, we are done
if [ "$_has_user_jre" -eq 1 ] && [ -n "$JDK_HOME" ] && _is_valid_jdk "$JDK_HOME"; then
return 0
fi
# 2. Gather candidates across macOS and Linux
_candidates=()
# macOS tool: /usr/libexec/java_home
if [ "$(uname -s 2>/dev/null)" = "Darwin" ] && [ -x "/usr/libexec/java_home" ]; then
_jh=$(/usr/libexec/java_home 2>/dev/null)
[ -n "$_jh" ] && _candidates+=("$_jh")
fi
# Linux tools: update-java-alternatives (Debian/Ubuntu) and readlink on java command
if command -v update-java-alternatives >/dev/null 2>&1; then
for _alt_path in $(update-java-alternatives -l 2>/dev/null | awk '{print $NF}'); do
[ -d "$_alt_path" ] && _candidates+=("$_alt_path")
done
fi
if command -v java >/dev/null 2>&1; then
_java_bin=$(command -v java 2>/dev/null)
if command -v readlink >/dev/null 2>&1; then
_real_java=$(readlink -f "$_java_bin" 2>/dev/null)
if [ -n "$_real_java" ] && [ -x "$_real_java" ]; then
_alt_home="$(dirname "$(dirname "$_real_java")")"
[ -n "$_alt_home" ] && _candidates+=("$_alt_home")
fi
fi
fi
# Cross-platform user managers (SDKMAN)
[ -d "$HOME/.sdkman/candidates/java/current" ] && _candidates+=("$HOME/.sdkman/candidates/java/current")
# macOS locations
if [ "$(uname -s 2>/dev/null)" = "Darwin" ]; then
# Homebrew OpenJDK
for _d in /opt/homebrew/opt/openjdk/libexec/openjdk.jdk/Contents/Home \
/opt/homebrew/opt/openjdk@*/libexec/openjdk.jdk/Contents/Home \
/usr/local/opt/openjdk/libexec/openjdk.jdk/Contents/Home; do
[ -d "$_d" ] && _candidates+=("$_d")
done
# Installed JVMs in /Library/Java/JavaVirtualMachines and ~/Library/...
# Version-sorted descending to prefer newer releases
for _d in $(
for _jvm in /Library/Java/JavaVirtualMachines/*/Contents/Home \
"$HOME/Library/Java/JavaVirtualMachines"/*/Contents/Home; do
[ -d "$_jvm" ] && echo "$_jvm"
done | sort -V -r 2>/dev/null
); do
_candidates+=("$_d")
done
# Android Studio bundled JBR/JDK
for _d in \
"/Applications/Android Studio.app/Contents/jbr/Contents/Home" \
"/Applications/Android Studio.app/Contents/jre/Contents/Home" \
"/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home" \
"$HOME/Applications/Android Studio.app/Contents/jbr/Contents/Home" \
"$HOME/Applications/Android Studio.app/Contents/jre/Contents/Home"
do
[ -d "$_d" ] && _candidates+=("$_d")
done
fi
# Linux / WSL locations
if [ "$(uname -s 2>/dev/null)" = "Linux" ]; then
# Default java symlink on Debian/Ubuntu
[ -d "/usr/lib/jvm/default-java" ] && _candidates+=("/usr/lib/jvm/default-java")
# Distribution JVMs in /usr/lib/jvm, version-sorted descending
for _d in $(
for _jvm in /usr/lib/jvm/*; do
[ -d "$_jvm" ] && echo "$_jvm"
done | sort -V -r 2>/dev/null
); do
_candidates+=("$_d")
done
for _d in \
"/usr/java/latest" \
"/usr/java/default" \
"/opt/android-studio/jbr" \
"/opt/android-studio/jre" \
"$HOME/android-studio/jbr" \
"$HOME/.local/share/JetBrains/Toolbox/apps/android-studio/jbr"
do
[ -d "$_d" ] && _candidates+=("$_d")
done
fi
# 3. Evaluate candidates: find best JRE (preferring SDK JREs) and best JDK
_best_jdk=""
_best_jre=""
for _cand in "${_candidates[@]}"; do
if [ -n "$_cand" ]; then
if _is_valid_jdk "$_cand"; then
[ -z "$_best_jdk" ] && _best_jdk="$_cand"
[ -z "$_best_jre" ] && _best_jre="$_cand"
elif _is_valid_jre "$_cand"; then
[ -z "$_best_jre" ] && _best_jre="$_cand"
fi
if [ -n "$_best_jdk" ] && [ -n "$_best_jre" ]; then
break
fi
fi
done
# 4. If no valid JAVA_HOME was set by user, configure it with best JRE (preferring SDK)
if [ "$_has_user_jre" -eq 0 ] && [ -n "$_best_jre" ]; then
export JAVA_HOME="$_best_jre"
_add_to_path "$JAVA_HOME/bin"
fi
# 5. If no SDK/JDK_HOME is set, configure it with best JDK
if [ -z "$JDK_HOME" ] || ! _is_valid_jdk "$JDK_HOME"; then
if _is_valid_jdk "${JAVA_HOME:-}"; then
export JDK_HOME="$JAVA_HOME"
elif [ -n "$_best_jdk" ]; then
export JDK_HOME="$_best_jdk"
_add_to_path "$_best_jdk/bin"
fi
fi
}
_setup_java
unset -f _setup_java _is_valid_jre _is_valid_jdk _add_to_path