# 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