160 lines
5.7 KiB
Bash
Executable File
160 lines
5.7 KiB
Bash
Executable File
# Setup Java environment (JAVA_HOME, JDK_HOME, and PATH)
|
|
_setup_java() {
|
|
[ -n "$ZSH_VERSION" ] && setopt localoptions nonomatch nullglob
|
|
|
|
_is_valid_jre() {
|
|
[ -n "$1" ] && [ -d "$1" ] && [ -x "$1/bin/java" ]
|
|
}
|
|
|
|
_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
|