Skip to content

Instantly share code, notes, and snippets.

@abd3lraouf
Last active January 18, 2026 19:50
Show Gist options
  • Select an option

  • Save abd3lraouf/1db9bf863144802733bfd29bb5dada87 to your computer and use it in GitHub Desktop.

Select an option

Save abd3lraouf/1db9bf863144802733bfd29bb5dada87 to your computer and use it in GitHub Desktop.

Revisions

  1. abd3lraouf revised this gist Nov 3, 2025. No changes.
  2. abd3lraouf revised this gist Nov 3, 2025. No changes.
  3. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions install.sh
    Original file line number Diff line number Diff line change
    @@ -124,14 +124,14 @@ get_jdk_version() {
    # Source SDKMAN and get current version
    local sdkman_init="${SDKMAN_DIR:-$HOME/.sdkman}/bin/sdkman-init.sh"
    if [[ -f "$sdkman_init" ]]; then
    # Temporarily disable -u for sourcing SDKMAN (it has undefined variables)
    # Temporarily disable -u for sourcing SDKMAN and calling sdk (they have undefined variables)
    set +u
    # shellcheck source=/dev/null
    source "$sdkman_init" 2>/dev/null || true
    set -u

    local version
    version="$(sdk current java 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+[^[:space:]]*' || echo "unknown")"
    set -u
    echo "$version"
    else
    echo "unknown"
  4. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 7 additions and 4 deletions.
    11 changes: 7 additions & 4 deletions install.sh
    Original file line number Diff line number Diff line change
    @@ -43,12 +43,11 @@ readonly BLUE='\033[0;34m'
    readonly BOLD='\033[1m'
    readonly NC='\033[0m' # No Color

    # Cleanup on error
    # Cleanup on error - silently exit (specific errors are already shown)
    cleanup() {
    local exit_code=$?
    if [ $exit_code -ne 0 ]; then
    error "Script failed with exit code $exit_code"
    fi
    # Exit silently - specific error messages are already displayed
    exit $exit_code
    }

    trap cleanup EXIT
    @@ -125,8 +124,12 @@ get_jdk_version() {
    # Source SDKMAN and get current version
    local sdkman_init="${SDKMAN_DIR:-$HOME/.sdkman}/bin/sdkman-init.sh"
    if [[ -f "$sdkman_init" ]]; then
    # Temporarily disable -u for sourcing SDKMAN (it has undefined variables)
    set +u
    # shellcheck source=/dev/null
    source "$sdkman_init" 2>/dev/null || true
    set -u

    local version
    version="$(sdk current java 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+[^[:space:]]*' || echo "unknown")"
    echo "$version"
  5. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 27 additions and 0 deletions.
    27 changes: 27 additions & 0 deletions install.sh
    Original file line number Diff line number Diff line change
    @@ -164,6 +164,33 @@ check_existing_setup() {

    # Verify sudo access
    verify_sudo() {
    # Try non-interactive sudo first
    if sudo -n true 2>/dev/null; then
    # Already authenticated
    # Keep sudo alive
    while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null &
    return 0
    fi

    # Check if running non-interactively
    if ! [ -t 0 ]; then
    error "This script requires sudo access"
    echo ""
    echo "When running via pipe, sudo cannot prompt for password."
    echo "Please authenticate sudo first, then re-run:"
    echo ""
    echo " sudo -v"
    echo " curl -fsSL https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/install.sh | bash -s install"
    echo ""
    echo "Or download and run directly:"
    echo ""
    echo " curl -O https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/install.sh"
    echo " chmod +x install.sh"
    echo " ./install.sh install"
    exit 1
    fi

    # Interactive mode - can prompt
    if ! sudo -v; then
    error "Sudo privileges required"
    exit 1
  6. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 6 additions and 3 deletions.
    9 changes: 6 additions & 3 deletions install.sh
    Original file line number Diff line number Diff line change
    @@ -22,11 +22,14 @@
    # - sudo privileges
    ################################################################################

    set -euo pipefail
    set -eo pipefail

    # Constants
    readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}" 2>/dev/null || echo "install.sh")"
    # Constants (temporarily disable -u for BASH_SOURCE check)
    readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]:-install.sh}")"
    readonly SCRIPT_VERSION="1.0.0"

    # Re-enable unbound variable checking
    set -u
    readonly TARGET_DIR="/Library/Java/JavaVirtualMachines/sdkman-current"
    readonly CONTENTS_DIR="${TARGET_DIR}/Contents"
    readonly HOME_LINK="${CONTENTS_DIR}/Home"
  7. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 48 additions and 35 deletions.
    83 changes: 48 additions & 35 deletions install.sh
    Original file line number Diff line number Diff line change
    @@ -357,41 +357,54 @@ verify_setup() {
    ################################################################################

    show_help() {
    printf "${BOLD}${SCRIPT_NAME}${NC} - Version ${SCRIPT_VERSION}\n\n"
    printf "${BOLD}DESCRIPTION${NC}\n"
    printf " Configure macOS to recognize SDKMAN-installed JDKs through /usr/libexec/java_home\n"
    printf " by creating a proper directory structure in /Library/Java/JavaVirtualMachines.\n\n"
    printf "${BOLD}USAGE${NC}\n"
    printf " ${SCRIPT_NAME} [COMMAND]\n\n"
    printf "${BOLD}COMMANDS${NC}\n"
    printf " install Set up the SDKMAN JDK integration (default)\n"
    printf " uninstall Remove the SDKMAN JDK integration\n"
    printf " verify Verify the setup is working correctly\n"
    printf " help Display this help message\n\n"
    printf "${BOLD}EXAMPLES${NC}\n"
    printf " # Install the integration\n"
    printf " ${SCRIPT_NAME} install\n\n"
    printf " # Verify it's working\n"
    printf " ${SCRIPT_NAME} verify\n\n"
    printf " # Remove the integration\n"
    printf " ${SCRIPT_NAME} uninstall\n\n"
    printf "${BOLD}HOW IT WORKS${NC}\n"
    printf " 1. Creates /Library/Java/JavaVirtualMachines/sdkman-current/Contents/\n"
    printf " 2. Symlinks Contents/Home to SDKMAN's current JDK\n"
    printf " 3. Creates Info.plist with proper metadata\n"
    printf " 4. Sets version to 9999 to ensure it's always selected\n\n"
    printf "${BOLD}REQUIREMENTS${NC}\n"
    printf " - macOS\n"
    printf " - SDKMAN installed with at least one JDK\n"
    printf " - sudo privileges\n\n"
    printf "${BOLD}FILES CREATED${NC}\n"
    printf " ${TARGET_DIR}/\n"
    printf " ${CONTENTS_DIR}/\n"
    printf " ${HOME_LINK} (symlink)\n"
    printf " ${PLIST_FILE}\n\n"
    printf "${BOLD}MORE INFO${NC}\n"
    printf " - SDKMAN: https://sdkman.io/\n"
    printf " - Report issues: https://github.com/anthropics/claude-code/issues\n\n"
    cat << 'EOF'
    install.sh - Version 1.0.0
    DESCRIPTION
    Configure macOS to recognize SDKMAN-installed JDKs through /usr/libexec/java_home
    by creating a proper directory structure in /Library/Java/JavaVirtualMachines.
    USAGE
    install.sh [COMMAND]
    COMMANDS
    install Set up the SDKMAN JDK integration (default)
    uninstall Remove the SDKMAN JDK integration
    verify Verify the setup is working correctly
    help Display this help message
    EXAMPLES
    # Install the integration
    install.sh install
    # Verify it's working
    install.sh verify
    # Remove the integration
    install.sh uninstall
    HOW IT WORKS
    1. Creates /Library/Java/JavaVirtualMachines/sdkman-current/Contents/
    2. Symlinks Contents/Home to SDKMAN's current JDK
    3. Creates Info.plist with proper metadata
    4. Sets version to 9999 to ensure it's always selected
    REQUIREMENTS
    - macOS
    - SDKMAN installed with at least one JDK
    - sudo privileges
    FILES CREATED
    /Library/Java/JavaVirtualMachines/sdkman-current/
    /Library/Java/JavaVirtualMachines/sdkman-current/Contents/
    /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home (symlink)
    /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Info.plist
    MORE INFO
    - SDKMAN: https://sdkman.io/
    - Gist: https://gist.github.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87
    EOF
    }

    ################################################################################
  8. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 48 additions and 53 deletions.
    101 changes: 48 additions & 53 deletions install.sh
    Original file line number Diff line number Diff line change
    @@ -192,12 +192,20 @@ install_setup() {
    # Check for existing setup
    if check_existing_setup; then
    warn "Existing setup found at $TARGET_DIR"
    read -rp "Remove and reinstall? (y/N): " response
    if [[ "$response" =~ ^[Yy]$ ]]; then
    uninstall_setup

    # Check if running interactively (can prompt)
    if [ -t 0 ]; then
    read -rp "Remove and reinstall? (y/N): " response
    if [[ "$response" =~ ^[Yy]$ ]]; then
    uninstall_setup
    else
    info "Installation cancelled"
    exit 0
    fi
    else
    info "Installation cancelled"
    exit 0
    # Non-interactive: auto-reinstall
    info "Non-interactive mode: auto-reinstalling..."
    uninstall_setup
    fi
    fi

    @@ -349,54 +357,41 @@ verify_setup() {
    ################################################################################

    show_help() {
    cat << EOF
    ${BOLD}${SCRIPT_NAME}${NC} - Version ${SCRIPT_VERSION}
    ${BOLD}DESCRIPTION${NC}
    Configure macOS to recognize SDKMAN-installed JDKs through /usr/libexec/java_home
    by creating a proper directory structure in /Library/Java/JavaVirtualMachines.
    ${BOLD}USAGE${NC}
    ${SCRIPT_NAME} [COMMAND]
    ${BOLD}COMMANDS${NC}
    install Set up the SDKMAN JDK integration (default)
    uninstall Remove the SDKMAN JDK integration
    verify Verify the setup is working correctly
    help Display this help message
    ${BOLD}EXAMPLES${NC}
    # Install the integration
    ${SCRIPT_NAME} install
    # Verify it's working
    ${SCRIPT_NAME} verify
    # Remove the integration
    ${SCRIPT_NAME} uninstall
    ${BOLD}HOW IT WORKS${NC}
    1. Creates /Library/Java/JavaVirtualMachines/sdkman-current/Contents/
    2. Symlinks Contents/Home to SDKMAN's current JDK
    3. Creates Info.plist with proper metadata
    4. Sets version to 9999 to ensure it's always selected
    ${BOLD}REQUIREMENTS${NC}
    - macOS
    - SDKMAN installed with at least one JDK
    - sudo privileges
    ${BOLD}FILES CREATED${NC}
    ${TARGET_DIR}/
    ${CONTENTS_DIR}/
    ${HOME_LINK} (symlink)
    ${PLIST_FILE}
    ${BOLD}MORE INFO${NC}
    - SDKMAN: https://sdkman.io/
    - Report issues: https://github.com/anthropics/claude-code/issues
    EOF
    printf "${BOLD}${SCRIPT_NAME}${NC} - Version ${SCRIPT_VERSION}\n\n"
    printf "${BOLD}DESCRIPTION${NC}\n"
    printf " Configure macOS to recognize SDKMAN-installed JDKs through /usr/libexec/java_home\n"
    printf " by creating a proper directory structure in /Library/Java/JavaVirtualMachines.\n\n"
    printf "${BOLD}USAGE${NC}\n"
    printf " ${SCRIPT_NAME} [COMMAND]\n\n"
    printf "${BOLD}COMMANDS${NC}\n"
    printf " install Set up the SDKMAN JDK integration (default)\n"
    printf " uninstall Remove the SDKMAN JDK integration\n"
    printf " verify Verify the setup is working correctly\n"
    printf " help Display this help message\n\n"
    printf "${BOLD}EXAMPLES${NC}\n"
    printf " # Install the integration\n"
    printf " ${SCRIPT_NAME} install\n\n"
    printf " # Verify it's working\n"
    printf " ${SCRIPT_NAME} verify\n\n"
    printf " # Remove the integration\n"
    printf " ${SCRIPT_NAME} uninstall\n\n"
    printf "${BOLD}HOW IT WORKS${NC}\n"
    printf " 1. Creates /Library/Java/JavaVirtualMachines/sdkman-current/Contents/\n"
    printf " 2. Symlinks Contents/Home to SDKMAN's current JDK\n"
    printf " 3. Creates Info.plist with proper metadata\n"
    printf " 4. Sets version to 9999 to ensure it's always selected\n\n"
    printf "${BOLD}REQUIREMENTS${NC}\n"
    printf " - macOS\n"
    printf " - SDKMAN installed with at least one JDK\n"
    printf " - sudo privileges\n\n"
    printf "${BOLD}FILES CREATED${NC}\n"
    printf " ${TARGET_DIR}/\n"
    printf " ${CONTENTS_DIR}/\n"
    printf " ${HOME_LINK} (symlink)\n"
    printf " ${PLIST_FILE}\n\n"
    printf "${BOLD}MORE INFO${NC}\n"
    printf " - SDKMAN: https://sdkman.io/\n"
    printf " - Report issues: https://github.com/anthropics/claude-code/issues\n\n"
    }

    ################################################################################
  9. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion install.sh
    Original file line number Diff line number Diff line change
    @@ -25,7 +25,7 @@
    set -euo pipefail

    # Constants
    readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]:-install.sh}")"
    readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}" 2>/dev/null || echo "install.sh")"
    readonly SCRIPT_VERSION="1.0.0"
    readonly TARGET_DIR="/Library/Java/JavaVirtualMachines/sdkman-current"
    readonly CONTENTS_DIR="${TARGET_DIR}/Contents"
  10. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion install.sh
    Original file line number Diff line number Diff line change
    @@ -25,7 +25,7 @@
    set -euo pipefail

    # Constants
    readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
    readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]:-install.sh}")"
    readonly SCRIPT_VERSION="1.0.0"
    readonly TARGET_DIR="/Library/Java/JavaVirtualMachines/sdkman-current"
    readonly CONTENTS_DIR="${TARGET_DIR}/Contents"
  11. abd3lraouf revised this gist Nov 3, 2025. 2 changed files with 3 additions and 88 deletions.
    6 changes: 3 additions & 3 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    **TL;DR:** Your SDKMAN Java installs are invisible to macOS. This fixes it.

    ```bash
    curl -fsSL https://gist.github.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw | bash -s install
    curl -fsSL https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/install.sh | bash -s install
    ```

    ## The Itch
    @@ -22,7 +22,7 @@ When you `sdk use java 17`, the integration follows automatically. No re-running

    ```bash
    # One-liner (recommended)
    curl -fsSL https://gist.github.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw | bash -s install
    curl -fsSL https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/install.sh | bash -s install

    # Or download first
    curl -O https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/install.sh
    @@ -82,4 +82,4 @@ Bookmark it. Share it. Clone it.

    **Abdelraouf Sabri** · [@abd3lraouf](https://github.com/abd3lraouf) · [LinkedIn](https://linkedin.com/in/abd3lraouf)

    *MIT License. Use it. Fork it. Fix it.*
    *MIT License. Use it. Fork it. Fix it.*
    85 changes: 0 additions & 85 deletions SDKMAN_JAVA_HOME_README.md
    Original file line number Diff line number Diff line change
    @@ -1,85 +0,0 @@
    # SDKMAN ↔ macOS Java Integration

    **TL;DR:** Your SDKMAN Java installs are invisible to macOS. This fixes it.

    ```bash
    curl -fsSL https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/install.sh | bash -s install
    ```

    ## The Itch

    You installed Java via SDKMAN. Xcode build phases fail. `java_home` returns nothing. Tools can't find your JDK. You know it's there, but macOS doesn't.

    Classic UNIX mismatch: SDKMAN installs to `~/.sdkman/candidates/java/`, macOS looks in `/Library/Java/JavaVirtualMachines/`. They'll never meet.

    ## What This Does

    Creates a symlink bridge with proper metadata so `/usr/libexec/java_home` recognizes your SDKMAN installation. One command, permanent fix.

    When you `sdk use java 17`, the integration follows automatically. No re-running scripts.

    ## Install

    ```bash
    # One-liner (recommended)
    curl -fsSL https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/install.sh | bash -s install

    # Or download first
    curl -O https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/install.sh
    chmod +x install.sh
    ./install.sh
    ```

    Requires: macOS + SDKMAN with at least one JDK + sudo

    ## Verify

    ```bash
    /usr/libexec/java_home
    # /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home

    java -version
    # Works from anywhere now
    ```

    ## Under the Hood

    ```
    /Library/Java/JavaVirtualMachines/sdkman-current/
    ├── Contents/
    │ ├── Home → ~/.sdkman/candidates/java/current
    │ └── Info.plist (version: 9999 = always default)
    ```

    Standard macOS JDK structure. The symlink tracks SDKMAN's `current` link, so switching versions just works.

    ## Commands

    ```bash
    ./install.sh verify # Check if working
    ./install.sh uninstall # Clean removal
    ./install.sh help # Full docs
    ```

    ## Why Version 9999?

    Forces this to be the default when multiple JDKs exist. `/usr/libexec/java_home` picks the highest version number. If you don't want this behavior, edit `Info.plist` after install.

    ## Uninstall

    ```bash
    ./install.sh uninstall
    # Or: sudo rm -rf /Library/Java/JavaVirtualMachines/sdkman-current
    ```

    ## Permanent Link

    **Gist:** https://gist.github.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87

    Bookmark it. Share it. Clone it.

    ---

    **Abdelraouf Sabri** · [@abd3lraouf](https://github.com/abd3lraouf) · [LinkedIn](https://linkedin.com/in/abd3lraouf)

    *MIT License. Use it. Fork it. Fix it.*
  12. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 85 additions and 0 deletions.
    85 changes: 85 additions & 0 deletions SDKMAN_JAVA_HOME_README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,85 @@
    # SDKMAN ↔ macOS Java Integration

    **TL;DR:** Your SDKMAN Java installs are invisible to macOS. This fixes it.

    ```bash
    curl -fsSL https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/install.sh | bash -s install
    ```

    ## The Itch

    You installed Java via SDKMAN. Xcode build phases fail. `java_home` returns nothing. Tools can't find your JDK. You know it's there, but macOS doesn't.

    Classic UNIX mismatch: SDKMAN installs to `~/.sdkman/candidates/java/`, macOS looks in `/Library/Java/JavaVirtualMachines/`. They'll never meet.

    ## What This Does

    Creates a symlink bridge with proper metadata so `/usr/libexec/java_home` recognizes your SDKMAN installation. One command, permanent fix.

    When you `sdk use java 17`, the integration follows automatically. No re-running scripts.

    ## Install

    ```bash
    # One-liner (recommended)
    curl -fsSL https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/install.sh | bash -s install

    # Or download first
    curl -O https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/install.sh
    chmod +x install.sh
    ./install.sh
    ```

    Requires: macOS + SDKMAN with at least one JDK + sudo

    ## Verify

    ```bash
    /usr/libexec/java_home
    # /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home

    java -version
    # Works from anywhere now
    ```

    ## Under the Hood

    ```
    /Library/Java/JavaVirtualMachines/sdkman-current/
    ├── Contents/
    │ ├── Home → ~/.sdkman/candidates/java/current
    │ └── Info.plist (version: 9999 = always default)
    ```

    Standard macOS JDK structure. The symlink tracks SDKMAN's `current` link, so switching versions just works.

    ## Commands

    ```bash
    ./install.sh verify # Check if working
    ./install.sh uninstall # Clean removal
    ./install.sh help # Full docs
    ```

    ## Why Version 9999?

    Forces this to be the default when multiple JDKs exist. `/usr/libexec/java_home` picks the highest version number. If you don't want this behavior, edit `Info.plist` after install.

    ## Uninstall

    ```bash
    ./install.sh uninstall
    # Or: sudo rm -rf /Library/Java/JavaVirtualMachines/sdkman-current
    ```

    ## Permanent Link

    **Gist:** https://gist.github.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87

    Bookmark it. Share it. Clone it.

    ---

    **Abdelraouf Sabri** · [@abd3lraouf](https://github.com/abd3lraouf) · [LinkedIn](https://linkedin.com/in/abd3lraouf)

    *MIT License. Use it. Fork it. Fix it.*
  13. abd3lraouf renamed this gist Nov 3, 2025. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  14. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 8 additions and 8 deletions.
    16 changes: 8 additions & 8 deletions SDKMAN_JAVA_HOME_README.md
    Original file line number Diff line number Diff line change
    @@ -25,9 +25,9 @@ When you `sdk use java 17`, the integration follows automatically. No re-running
    curl -fsSL https://gist.github.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw | bash -s install

    # Or download first
    curl -O https://gist.github.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/setup_sdkman_java_home.sh
    chmod +x setup_sdkman_java_home.sh
    ./setup_sdkman_java_home.sh install
    curl -O https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/install.sh
    chmod +x install.sh
    ./install.sh
    ```

    Requires: macOS + SDKMAN with at least one JDK + sudo
    @@ -56,9 +56,9 @@ Standard macOS JDK structure. The symlink tracks SDKMAN's `current` link, so swi
    ## Commands

    ```bash
    ./setup_sdkman_java_home.sh verify # Check if working
    ./setup_sdkman_java_home.sh uninstall # Clean removal
    ./setup_sdkman_java_home.sh help # Full docs
    ./install.sh verify # Check if working
    ./install.sh uninstall # Clean removal
    ./install.sh help # Full docs
    ```

    ## Why Version 9999?
    @@ -68,13 +68,13 @@ Forces this to be the default when multiple JDKs exist. `/usr/libexec/java_home`
    ## Uninstall

    ```bash
    ./setup_sdkman_java_home.sh uninstall
    ./install.sh uninstall
    # Or: sudo rm -rf /Library/Java/JavaVirtualMachines/sdkman-current
    ```

    ## Permanent Link

    **Gist:** [git.io/sdkman-java](https://gist.github.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87)
    **Gist:** https://gist.github.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87

    Bookmark it. Share it. Clone it.

  15. abd3lraouf renamed this gist Nov 3, 2025. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  16. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 43 additions and 75 deletions.
    118 changes: 43 additions & 75 deletions SDKMAN_JAVA_HOME_README.md
    Original file line number Diff line number Diff line change
    @@ -1,117 +1,85 @@
    # SDKMAN + macOS Java Home Integration
    # SDKMAN macOS Java Integration

    Make macOS recognize your SDKMAN Java installations.

    ## The Problem

    Xcode and macOS tools can't find Java when it's installed via SDKMAN. They look for Java in `/Library/Java/JavaVirtualMachines` but SDKMAN installs to `~/.sdkman/candidates/java/`.

    ## The Solution

    This script creates a bridge between SDKMAN and macOS so tools like Xcode can find your Java installation.

    ## One-Line Install
    **TL;DR:** Your SDKMAN Java installs are invisible to macOS. This fixes it.

    ```bash
    curl -fsSL https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/setup_sdkman_java_home.sh | bash -s install
    curl -fsSL https://gist.github.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw | bash -s install
    ```

    ## Manual Install
    ## The Itch

    ```bash
    # Download
    curl -o setup_sdkman_java_home.sh https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/setup_sdkman_java_home.sh
    You installed Java via SDKMAN. Xcode build phases fail. `java_home` returns nothing. Tools can't find your JDK. You know it's there, but macOS doesn't.

    # Make executable
    chmod +x setup_sdkman_java_home.sh
    Classic UNIX mismatch: SDKMAN installs to `~/.sdkman/candidates/java/`, macOS looks in `/Library/Java/JavaVirtualMachines/`. They'll never meet.

    # Run
    ./setup_sdkman_java_home.sh install
    ```
    ## What This Does

    ## What You Need
    Creates a symlink bridge with proper metadata so `/usr/libexec/java_home` recognizes your SDKMAN installation. One command, permanent fix.

    - macOS
    - SDKMAN with at least one Java version installed
    - sudo access (you'll be prompted for your password)
    When you `sdk use java 17`, the integration follows automatically. No re-running scripts.

    ## Usage
    ## Install

    ```bash
    # Install
    ./setup_sdkman_java_home.sh install

    # Verify it's working
    ./setup_sdkman_java_home.sh verify
    # One-liner (recommended)
    curl -fsSL https://gist.github.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw | bash -s install

    # Uninstall
    ./setup_sdkman_java_home.sh uninstall
    # Or download first
    curl -O https://gist.github.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/setup_sdkman_java_home.sh
    chmod +x setup_sdkman_java_home.sh
    ./setup_sdkman_java_home.sh install
    ```

    ## Does It Work?
    Requires: macOS + SDKMAN with at least one JDK + sudo

    After installing, test it:
    ## Verify

    ```bash
    /usr/libexec/java_home
    # Should output: /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home
    # /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home

    /usr/libexec/java_home -V
    # Should show your SDKMAN Java version
    java -version
    # Works from anywhere now
    ```

    ## Switching Java Versions
    ## Under the Hood

    When you switch Java versions with SDKMAN:
    ```bash
    sdk use java 17.0.9-tem
    ```
    /Library/Java/JavaVirtualMachines/sdkman-current/
    ├── Contents/
    │ ├── Home → ~/.sdkman/candidates/java/current
    │ └── Info.plist (version: 9999 = always default)
    ```

    The integration automatically updates. No need to run the script again!

    ## Uninstall
    Standard macOS JDK structure. The symlink tracks SDKMAN's `current` link, so switching versions just works.

    ```bash
    ./setup_sdkman_java_home.sh uninstall
    ```
    ## Commands

    Or manually:
    ```bash
    sudo rm -rf /Library/Java/JavaVirtualMachines/sdkman-current
    ./setup_sdkman_java_home.sh verify # Check if working
    ./setup_sdkman_java_home.sh uninstall # Clean removal
    ./setup_sdkman_java_home.sh help # Full docs
    ```

    ## How It Works
    ## Why Version 9999?

    1. Creates a folder: `/Library/Java/JavaVirtualMachines/sdkman-current/Contents/`
    2. Links it to SDKMAN's current Java: `~/.sdkman/candidates/java/current`
    3. Adds metadata file so macOS recognizes it
    Forces this to be the default when multiple JDKs exist. `/usr/libexec/java_home` picks the highest version number. If you don't want this behavior, edit `Info.plist` after install.

    That's it. Simple symlink trick.

    ## Troubleshooting

    **"SDKMAN not found"**
    ```bash
    # Install SDKMAN first
    curl -s "https://get.sdkman.io" | bash
    ```
    ## Uninstall

    **"No current JDK set"**
    ```bash
    # Install Java
    sdk install java 21.0.9-amzn
    ./setup_sdkman_java_home.sh uninstall
    # Or: sudo rm -rf /Library/Java/JavaVirtualMachines/sdkman-current
    ```

    **"Permission denied"**
    - Make sure you have sudo access
    - You'll be prompted for your password
    ## Permanent Link

    ## Author
    **Gist:** [git.io/sdkman-java](https://gist.github.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87)

    **Abdelraouf Sabri**
    - GitHub: [@abd3lraouf](https://github.com/abd3lraouf)
    - LinkedIn: [abd3lraouf](https://linkedin.com/in/abd3lraouf)
    Bookmark it. Share it. Clone it.

    ---

    Found this helpful? Give it a ⭐
    **Abdelraouf Sabri** · [@abd3lraouf](https://github.com/abd3lraouf) · [LinkedIn](https://linkedin.com/in/abd3lraouf)

    *MIT License. Use it. Fork it. Fix it.*
  17. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 0 additions and 206 deletions.
    206 changes: 0 additions & 206 deletions SDKMAN_JAVA_HOME_README_SIMPLE.md
    Original file line number Diff line number Diff line change
    @@ -1,206 +0,0 @@
    # SDKMAN Java Home Integration for macOS

    A robust bash script to integrate SDKMAN-installed JDKs with macOS's `/usr/libexec/java_home` utility, enabling seamless Java detection for Xcode and other macOS development tools.

    ## The Problem

    `/usr/libexec/java_home` is macOS's standard way to locate Java installations, but it doesn't recognize SDKMAN-installed JDKs because:

    1. SDKMAN-installed JDKs don't follow the standard macOS JDK structure
    2. They're not located in `/Library/Java/JavaVirtualMachines` where macOS expects them

    This causes issues with:
    - Xcode build phases that require Java
    - Tools relying on `JAVA_HOME` from `/usr/libexec/java_home`
    - Shell scripts expecting standard Java detection

    ## The Solution

    This script creates a properly structured symlink in `/Library/Java/JavaVirtualMachines` that points to SDKMAN's current JDK, complete with the required `Info.plist` metadata that `/usr/libexec/java_home` needs.

    ### How It Works

    1. Creates `/Library/Java/JavaVirtualMachines/sdkman-current/Contents/`
    2. Symlinks `Contents/Home` to SDKMAN's current JDK (`~/.sdkman/candidates/java/current`)
    3. Generates `Info.plist` with proper metadata (version set to 9999 to ensure it's always selected)
    4. Automatically tracks SDKMAN's current JDK - when you switch versions with `sdk use java <version>`, the symlink follows

    ## Features

    -**Automatic vendor detection** - Recognizes Amazon Corretto, Eclipse Temurin, Azul Zulu, GraalVM, and more
    -**Dynamic JDK version extraction** - Reads actual version from SDKMAN
    -**Multiple commands** - Install, uninstall, verify, and help
    -**Safe operations** - Prompts before overwriting, validates prerequisites
    -**Comprehensive error handling** - Proper cleanup and detailed error messages
    -**ShellCheck compliant** - Follows bash best practices
    -**Idempotent** - Safe to run multiple times
    -**Professional output** - Colored messages with clear status indicators

    ## Requirements

    - macOS (Darwin)
    - [SDKMAN](https://sdkman.io/) installed with at least one JDK
    - sudo privileges (required to write to `/Library/Java/JavaVirtualMachines`)

    ## Installation

    ```bash
    # Download the script
    curl -o setup_sdkman_java_home.sh https://gist.githubusercontent.com/abd3lraouf/YOUR_GIST_ID/raw/setup_sdkman_java_home.sh

    # Make it executable
    chmod +x setup_sdkman_java_home.sh

    # Run the installation
    ./setup_sdkman_java_home.sh install
    ```

    ## Usage

    ```bash
    # Install the integration (requires sudo)
    ./setup_sdkman_java_home.sh install

    # Verify it's working
    ./setup_sdkman_java_home.sh verify

    # Check available Java VMs
    /usr/libexec/java_home -V

    # Get the current Java home path
    /usr/libexec/java_home

    # Remove the integration if needed
    ./setup_sdkman_java_home.sh uninstall

    # Display help
    ./setup_sdkman_java_home.sh help
    ```

    ## Example Output

    ```bash
    $ ./setup_sdkman_java_home.sh install

    === Installing SDKMAN JDK Integration ===

    ✓ SDKMAN found at /Users/username/.sdkman
    ℹ SDKMAN Current JDK: /Users/username/.sdkman/candidates/java/current
    ℹ Version: 21.0.9
    ℹ Vendor: Amazon Corretto
    ℹ Creating directory structure...
    ✓ Created /Library/Java/JavaVirtualMachines/sdkman-current/Contents
    ✓ Created symlink: /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home -> ~/.sdkman/candidates/java/current
    ✓ Created Info.plist
    ✓ Permissions set

    === Installation Complete ===
    ✓ SDKMAN JDK integration installed successfully

    $ /usr/libexec/java_home -V
    Matching Java Virtual Machines (1):
    9999 (arm64) "Amazon Corretto" - "SDKMAN Current JDK" /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home
    ```

    ## Commands

    | Command | Description |
    |---------|-------------|
    | `install` | Set up the SDKMAN JDK integration (default command) |
    | `uninstall` | Remove the integration and clean up all created files |
    | `verify` | Verify the setup is working correctly |
    | `help` | Display comprehensive help message |

    ## Files Created

    ```
    /Library/Java/JavaVirtualMachines/sdkman-current/
    ├── Contents/
    │ ├── Home -> ~/.sdkman/candidates/java/current (symlink)
    │ └── Info.plist
    ```

    ## Troubleshooting

    ### SDKMAN not found
    ```bash
    # Install SDKMAN
    curl -s "https://get.sdkman.io" | bash
    source ~/.sdkman/bin/sdkman-init.sh
    ```

    ### No current JDK set
    ```bash
    # Install a JDK
    sdk install java 21.0.9-amzn

    # Or set an existing one as current
    sdk use java 21.0.9-amzn
    ```

    ### Verification fails
    ```bash
    # Run the verify command for detailed diagnostics
    ./setup_sdkman_java_home.sh verify
    ```

    ### Switching JDK versions
    When you switch JDK versions with SDKMAN:
    ```bash
    sdk use java 17.0.9-tem
    ```
    The symlink automatically points to the new version - no need to re-run the script!

    ## Technical Details

    ### Why Version 9999?

    The `JVMPlatformVersion` is set to `9999` in `Info.plist` to ensure this JDK is always selected as the default by `/usr/libexec/java_home`. This is important because:

    - Other manually installed JDKs might exist on the system
    - `/usr/libexec/java_home` selects the highest version by default
    - This ensures SDKMAN's current JDK is always preferred

    ### Supported SDKMAN Vendors

    The script auto-detects these vendors from the JDK path:

    - `amzn` → Amazon Corretto
    - `tem` → Eclipse Temurin
    - `zulu` → Azul Zulu
    - `graal*` → GraalVM
    - `liberica` → BellSoft Liberica
    - `sapmchn` → SAP Machine
    - Others → SDKMAN (vendor-code)

    ## Use Cases

    - **Xcode Projects**: Build phases requiring Java (e.g., Kotlin/Native builds)
    - **Shell Scripts**: Scripts that use `JAVA_HOME=$(/usr/libexec/java_home)`
    - **Development Tools**: IDEs and tools expecting standard macOS Java detection
    - **CI/CD Pipelines**: macOS build environments using SDKMAN

    ## Contributing

    Found a bug or have a suggestion? Feel free to open an issue or submit improvements!

    ## License

    MIT License - feel free to use, modify, and distribute.

    ## Author

    **Abdelraouf Sabri**

    - GitHub: [@abd3lraouf](https://github.com/abd3lraouf)
    - LinkedIn: [abd3lraouf](https://linkedin.com/in/abd3lraouf)

    ## References

    - [SDKMAN Official Site](https://sdkman.io/)
    - [Apple Developer Documentation](https://developer.apple.com/)
    - `/usr/libexec/java_home` - macOS's Java detection utility (largely undocumented)

    ---

    *If this script helped you, consider giving it a ⭐ star!*
  18. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 56 additions and 145 deletions.
    201 changes: 56 additions & 145 deletions SDKMAN_JAVA_HOME_README.md
    Original file line number Diff line number Diff line change
    @@ -1,206 +1,117 @@
    # SDKMAN Java Home Integration for macOS
    # SDKMAN + macOS Java Home Integration

    A robust bash script to integrate SDKMAN-installed JDKs with macOS's `/usr/libexec/java_home` utility, enabling seamless Java detection for Xcode and other macOS development tools.
    Make macOS recognize your SDKMAN Java installations.

    ## The Problem

    `/usr/libexec/java_home` is macOS's standard way to locate Java installations, but it doesn't recognize SDKMAN-installed JDKs because:

    1. SDKMAN-installed JDKs don't follow the standard macOS JDK structure
    2. They're not located in `/Library/Java/JavaVirtualMachines` where macOS expects them

    This causes issues with:
    - Xcode build phases that require Java
    - Tools relying on `JAVA_HOME` from `/usr/libexec/java_home`
    - Shell scripts expecting standard Java detection
    Xcode and macOS tools can't find Java when it's installed via SDKMAN. They look for Java in `/Library/Java/JavaVirtualMachines` but SDKMAN installs to `~/.sdkman/candidates/java/`.

    ## The Solution

    This script creates a properly structured symlink in `/Library/Java/JavaVirtualMachines` that points to SDKMAN's current JDK, complete with the required `Info.plist` metadata that `/usr/libexec/java_home` needs.

    ### How It Works

    1. Creates `/Library/Java/JavaVirtualMachines/sdkman-current/Contents/`
    2. Symlinks `Contents/Home` to SDKMAN's current JDK (`~/.sdkman/candidates/java/current`)
    3. Generates `Info.plist` with proper metadata (version set to 9999 to ensure it's always selected)
    4. Automatically tracks SDKMAN's current JDK - when you switch versions with `sdk use java <version>`, the symlink follows

    ## Features

    -**Automatic vendor detection** - Recognizes Amazon Corretto, Eclipse Temurin, Azul Zulu, GraalVM, and more
    -**Dynamic JDK version extraction** - Reads actual version from SDKMAN
    -**Multiple commands** - Install, uninstall, verify, and help
    -**Safe operations** - Prompts before overwriting, validates prerequisites
    -**Comprehensive error handling** - Proper cleanup and detailed error messages
    -**ShellCheck compliant** - Follows bash best practices
    -**Idempotent** - Safe to run multiple times
    -**Professional output** - Colored messages with clear status indicators
    This script creates a bridge between SDKMAN and macOS so tools like Xcode can find your Java installation.

    ## Requirements
    ## One-Line Install

    - macOS (Darwin)
    - [SDKMAN](https://sdkman.io/) installed with at least one JDK
    - sudo privileges (required to write to `/Library/Java/JavaVirtualMachines`)
    ```bash
    curl -fsSL https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/setup_sdkman_java_home.sh | bash -s install
    ```

    ## Installation
    ## Manual Install

    ```bash
    # Download the script
    curl -o setup_sdkman_java_home.sh https://gist.githubusercontent.com/abd3lraouf/YOUR_GIST_ID/raw/setup_sdkman_java_home.sh
    # Download
    curl -o setup_sdkman_java_home.sh https://gist.githubusercontent.com/abd3lraouf/1db9bf863144802733bfd29bb5dada87/raw/setup_sdkman_java_home.sh

    # Make it executable
    # Make executable
    chmod +x setup_sdkman_java_home.sh

    # Run the installation
    # Run
    ./setup_sdkman_java_home.sh install
    ```

    ## What You Need

    - macOS
    - SDKMAN with at least one Java version installed
    - sudo access (you'll be prompted for your password)

    ## Usage

    ```bash
    # Install the integration (requires sudo)
    # Install
    ./setup_sdkman_java_home.sh install

    # Verify it's working
    ./setup_sdkman_java_home.sh verify

    # Check available Java VMs
    /usr/libexec/java_home -V

    # Get the current Java home path
    /usr/libexec/java_home

    # Remove the integration if needed
    # Uninstall
    ./setup_sdkman_java_home.sh uninstall

    # Display help
    ./setup_sdkman_java_home.sh help
    ```

    ## Example Output

    ```bash
    $ ./setup_sdkman_java_home.sh install

    === Installing SDKMAN JDK Integration ===

    ✓ SDKMAN found at /Users/username/.sdkman
    ℹ SDKMAN Current JDK: /Users/username/.sdkman/candidates/java/current
    ℹ Version: 21.0.9
    ℹ Vendor: Amazon Corretto
    ℹ Creating directory structure...
    ✓ Created /Library/Java/JavaVirtualMachines/sdkman-current/Contents
    ✓ Created symlink: /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home -> ~/.sdkman/candidates/java/current
    ✓ Created Info.plist
    ✓ Permissions set

    === Installation Complete ===
    ✓ SDKMAN JDK integration installed successfully

    $ /usr/libexec/java_home -V
    Matching Java Virtual Machines (1):
    9999 (arm64) "Amazon Corretto" - "SDKMAN Current JDK" /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home
    ```

    ## Commands
    ## Does It Work?

    | Command | Description |
    |---------|-------------|
    | `install` | Set up the SDKMAN JDK integration (default command) |
    | `uninstall` | Remove the integration and clean up all created files |
    | `verify` | Verify the setup is working correctly |
    | `help` | Display comprehensive help message |
    After installing, test it:

    ## Files Created
    ```bash
    /usr/libexec/java_home
    # Should output: /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home

    ```
    /Library/Java/JavaVirtualMachines/sdkman-current/
    ├── Contents/
    │ ├── Home -> ~/.sdkman/candidates/java/current (symlink)
    │ └── Info.plist
    /usr/libexec/java_home -V
    # Should show your SDKMAN Java version
    ```

    ## Troubleshooting
    ## Switching Java Versions

    ### SDKMAN not found
    When you switch Java versions with SDKMAN:
    ```bash
    # Install SDKMAN
    curl -s "https://get.sdkman.io" | bash
    source ~/.sdkman/bin/sdkman-init.sh
    sdk use java 17.0.9-tem
    ```

    ### No current JDK set
    ```bash
    # Install a JDK
    sdk install java 21.0.9-amzn
    The integration automatically updates. No need to run the script again!

    # Or set an existing one as current
    sdk use java 21.0.9-amzn
    ```
    ## Uninstall

    ### Verification fails
    ```bash
    # Run the verify command for detailed diagnostics
    ./setup_sdkman_java_home.sh verify
    ./setup_sdkman_java_home.sh uninstall
    ```

    ### Switching JDK versions
    When you switch JDK versions with SDKMAN:
    Or manually:
    ```bash
    sdk use java 17.0.9-tem
    sudo rm -rf /Library/Java/JavaVirtualMachines/sdkman-current
    ```
    The symlink automatically points to the new version - no need to re-run the script!

    ## Technical Details

    ### Why Version 9999?

    The `JVMPlatformVersion` is set to `9999` in `Info.plist` to ensure this JDK is always selected as the default by `/usr/libexec/java_home`. This is important because:

    - Other manually installed JDKs might exist on the system
    - `/usr/libexec/java_home` selects the highest version by default
    - This ensures SDKMAN's current JDK is always preferred

    ### Supported SDKMAN Vendors
    ## How It Works

    The script auto-detects these vendors from the JDK path:
    1. Creates a folder: `/Library/Java/JavaVirtualMachines/sdkman-current/Contents/`
    2. Links it to SDKMAN's current Java: `~/.sdkman/candidates/java/current`
    3. Adds metadata file so macOS recognizes it

    - `amzn` → Amazon Corretto
    - `tem` → Eclipse Temurin
    - `zulu` → Azul Zulu
    - `graal*` → GraalVM
    - `liberica` → BellSoft Liberica
    - `sapmchn` → SAP Machine
    - Others → SDKMAN (vendor-code)
    That's it. Simple symlink trick.

    ## Use Cases

    - **Xcode Projects**: Build phases requiring Java (e.g., Kotlin/Native builds)
    - **Shell Scripts**: Scripts that use `JAVA_HOME=$(/usr/libexec/java_home)`
    - **Development Tools**: IDEs and tools expecting standard macOS Java detection
    - **CI/CD Pipelines**: macOS build environments using SDKMAN

    ## Contributing
    ## Troubleshooting

    Found a bug or have a suggestion? Feel free to open an issue or submit improvements!
    **"SDKMAN not found"**
    ```bash
    # Install SDKMAN first
    curl -s "https://get.sdkman.io" | bash
    ```

    ## License
    **"No current JDK set"**
    ```bash
    # Install Java
    sdk install java 21.0.9-amzn
    ```

    MIT License - feel free to use, modify, and distribute.
    **"Permission denied"**
    - Make sure you have sudo access
    - You'll be prompted for your password

    ## Author

    **Abdelraouf Sabri**

    - GitHub: [@abd3lraouf](https://github.com/abd3lraouf)
    - LinkedIn: [abd3lraouf](https://linkedin.com/in/abd3lraouf)

    ## References

    - [SDKMAN Official Site](https://sdkman.io/)
    - [Apple Developer Documentation](https://developer.apple.com/)
    - `/usr/libexec/java_home` - macOS's Java detection utility (largely undocumented)

    ---

    *If this script helped you, consider giving it a ⭐ star!*
    Found this helpful? Give it a ⭐
  19. abd3lraouf revised this gist Nov 3, 2025. 1 changed file with 206 additions and 0 deletions.
    206 changes: 206 additions & 0 deletions SDKMAN_JAVA_HOME_README_SIMPLE.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,206 @@
    # SDKMAN Java Home Integration for macOS

    A robust bash script to integrate SDKMAN-installed JDKs with macOS's `/usr/libexec/java_home` utility, enabling seamless Java detection for Xcode and other macOS development tools.

    ## The Problem

    `/usr/libexec/java_home` is macOS's standard way to locate Java installations, but it doesn't recognize SDKMAN-installed JDKs because:

    1. SDKMAN-installed JDKs don't follow the standard macOS JDK structure
    2. They're not located in `/Library/Java/JavaVirtualMachines` where macOS expects them

    This causes issues with:
    - Xcode build phases that require Java
    - Tools relying on `JAVA_HOME` from `/usr/libexec/java_home`
    - Shell scripts expecting standard Java detection

    ## The Solution

    This script creates a properly structured symlink in `/Library/Java/JavaVirtualMachines` that points to SDKMAN's current JDK, complete with the required `Info.plist` metadata that `/usr/libexec/java_home` needs.

    ### How It Works

    1. Creates `/Library/Java/JavaVirtualMachines/sdkman-current/Contents/`
    2. Symlinks `Contents/Home` to SDKMAN's current JDK (`~/.sdkman/candidates/java/current`)
    3. Generates `Info.plist` with proper metadata (version set to 9999 to ensure it's always selected)
    4. Automatically tracks SDKMAN's current JDK - when you switch versions with `sdk use java <version>`, the symlink follows

    ## Features

    -**Automatic vendor detection** - Recognizes Amazon Corretto, Eclipse Temurin, Azul Zulu, GraalVM, and more
    -**Dynamic JDK version extraction** - Reads actual version from SDKMAN
    -**Multiple commands** - Install, uninstall, verify, and help
    -**Safe operations** - Prompts before overwriting, validates prerequisites
    -**Comprehensive error handling** - Proper cleanup and detailed error messages
    -**ShellCheck compliant** - Follows bash best practices
    -**Idempotent** - Safe to run multiple times
    -**Professional output** - Colored messages with clear status indicators

    ## Requirements

    - macOS (Darwin)
    - [SDKMAN](https://sdkman.io/) installed with at least one JDK
    - sudo privileges (required to write to `/Library/Java/JavaVirtualMachines`)

    ## Installation

    ```bash
    # Download the script
    curl -o setup_sdkman_java_home.sh https://gist.githubusercontent.com/abd3lraouf/YOUR_GIST_ID/raw/setup_sdkman_java_home.sh

    # Make it executable
    chmod +x setup_sdkman_java_home.sh

    # Run the installation
    ./setup_sdkman_java_home.sh install
    ```

    ## Usage

    ```bash
    # Install the integration (requires sudo)
    ./setup_sdkman_java_home.sh install

    # Verify it's working
    ./setup_sdkman_java_home.sh verify

    # Check available Java VMs
    /usr/libexec/java_home -V

    # Get the current Java home path
    /usr/libexec/java_home

    # Remove the integration if needed
    ./setup_sdkman_java_home.sh uninstall

    # Display help
    ./setup_sdkman_java_home.sh help
    ```

    ## Example Output

    ```bash
    $ ./setup_sdkman_java_home.sh install

    === Installing SDKMAN JDK Integration ===

    ✓ SDKMAN found at /Users/username/.sdkman
    ℹ SDKMAN Current JDK: /Users/username/.sdkman/candidates/java/current
    ℹ Version: 21.0.9
    ℹ Vendor: Amazon Corretto
    ℹ Creating directory structure...
    ✓ Created /Library/Java/JavaVirtualMachines/sdkman-current/Contents
    ✓ Created symlink: /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home -> ~/.sdkman/candidates/java/current
    ✓ Created Info.plist
    ✓ Permissions set

    === Installation Complete ===
    ✓ SDKMAN JDK integration installed successfully

    $ /usr/libexec/java_home -V
    Matching Java Virtual Machines (1):
    9999 (arm64) "Amazon Corretto" - "SDKMAN Current JDK" /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home
    ```

    ## Commands

    | Command | Description |
    |---------|-------------|
    | `install` | Set up the SDKMAN JDK integration (default command) |
    | `uninstall` | Remove the integration and clean up all created files |
    | `verify` | Verify the setup is working correctly |
    | `help` | Display comprehensive help message |

    ## Files Created

    ```
    /Library/Java/JavaVirtualMachines/sdkman-current/
    ├── Contents/
    │ ├── Home -> ~/.sdkman/candidates/java/current (symlink)
    │ └── Info.plist
    ```

    ## Troubleshooting

    ### SDKMAN not found
    ```bash
    # Install SDKMAN
    curl -s "https://get.sdkman.io" | bash
    source ~/.sdkman/bin/sdkman-init.sh
    ```

    ### No current JDK set
    ```bash
    # Install a JDK
    sdk install java 21.0.9-amzn

    # Or set an existing one as current
    sdk use java 21.0.9-amzn
    ```

    ### Verification fails
    ```bash
    # Run the verify command for detailed diagnostics
    ./setup_sdkman_java_home.sh verify
    ```

    ### Switching JDK versions
    When you switch JDK versions with SDKMAN:
    ```bash
    sdk use java 17.0.9-tem
    ```
    The symlink automatically points to the new version - no need to re-run the script!

    ## Technical Details

    ### Why Version 9999?

    The `JVMPlatformVersion` is set to `9999` in `Info.plist` to ensure this JDK is always selected as the default by `/usr/libexec/java_home`. This is important because:

    - Other manually installed JDKs might exist on the system
    - `/usr/libexec/java_home` selects the highest version by default
    - This ensures SDKMAN's current JDK is always preferred

    ### Supported SDKMAN Vendors

    The script auto-detects these vendors from the JDK path:

    - `amzn` → Amazon Corretto
    - `tem` → Eclipse Temurin
    - `zulu` → Azul Zulu
    - `graal*` → GraalVM
    - `liberica` → BellSoft Liberica
    - `sapmchn` → SAP Machine
    - Others → SDKMAN (vendor-code)

    ## Use Cases

    - **Xcode Projects**: Build phases requiring Java (e.g., Kotlin/Native builds)
    - **Shell Scripts**: Scripts that use `JAVA_HOME=$(/usr/libexec/java_home)`
    - **Development Tools**: IDEs and tools expecting standard macOS Java detection
    - **CI/CD Pipelines**: macOS build environments using SDKMAN

    ## Contributing

    Found a bug or have a suggestion? Feel free to open an issue or submit improvements!

    ## License

    MIT License - feel free to use, modify, and distribute.

    ## Author

    **Abdelraouf Sabri**

    - GitHub: [@abd3lraouf](https://github.com/abd3lraouf)
    - LinkedIn: [abd3lraouf](https://linkedin.com/in/abd3lraouf)

    ## References

    - [SDKMAN Official Site](https://sdkman.io/)
    - [Apple Developer Documentation](https://developer.apple.com/)
    - `/usr/libexec/java_home` - macOS's Java detection utility (largely undocumented)

    ---

    *If this script helped you, consider giving it a ⭐ star!*
  20. abd3lraouf created this gist Nov 3, 2025.
    206 changes: 206 additions & 0 deletions SDKMAN_JAVA_HOME_README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,206 @@
    # SDKMAN Java Home Integration for macOS

    A robust bash script to integrate SDKMAN-installed JDKs with macOS's `/usr/libexec/java_home` utility, enabling seamless Java detection for Xcode and other macOS development tools.

    ## The Problem

    `/usr/libexec/java_home` is macOS's standard way to locate Java installations, but it doesn't recognize SDKMAN-installed JDKs because:

    1. SDKMAN-installed JDKs don't follow the standard macOS JDK structure
    2. They're not located in `/Library/Java/JavaVirtualMachines` where macOS expects them

    This causes issues with:
    - Xcode build phases that require Java
    - Tools relying on `JAVA_HOME` from `/usr/libexec/java_home`
    - Shell scripts expecting standard Java detection

    ## The Solution

    This script creates a properly structured symlink in `/Library/Java/JavaVirtualMachines` that points to SDKMAN's current JDK, complete with the required `Info.plist` metadata that `/usr/libexec/java_home` needs.

    ### How It Works

    1. Creates `/Library/Java/JavaVirtualMachines/sdkman-current/Contents/`
    2. Symlinks `Contents/Home` to SDKMAN's current JDK (`~/.sdkman/candidates/java/current`)
    3. Generates `Info.plist` with proper metadata (version set to 9999 to ensure it's always selected)
    4. Automatically tracks SDKMAN's current JDK - when you switch versions with `sdk use java <version>`, the symlink follows

    ## Features

    -**Automatic vendor detection** - Recognizes Amazon Corretto, Eclipse Temurin, Azul Zulu, GraalVM, and more
    -**Dynamic JDK version extraction** - Reads actual version from SDKMAN
    -**Multiple commands** - Install, uninstall, verify, and help
    -**Safe operations** - Prompts before overwriting, validates prerequisites
    -**Comprehensive error handling** - Proper cleanup and detailed error messages
    -**ShellCheck compliant** - Follows bash best practices
    -**Idempotent** - Safe to run multiple times
    -**Professional output** - Colored messages with clear status indicators

    ## Requirements

    - macOS (Darwin)
    - [SDKMAN](https://sdkman.io/) installed with at least one JDK
    - sudo privileges (required to write to `/Library/Java/JavaVirtualMachines`)

    ## Installation

    ```bash
    # Download the script
    curl -o setup_sdkman_java_home.sh https://gist.githubusercontent.com/abd3lraouf/YOUR_GIST_ID/raw/setup_sdkman_java_home.sh

    # Make it executable
    chmod +x setup_sdkman_java_home.sh

    # Run the installation
    ./setup_sdkman_java_home.sh install
    ```

    ## Usage

    ```bash
    # Install the integration (requires sudo)
    ./setup_sdkman_java_home.sh install

    # Verify it's working
    ./setup_sdkman_java_home.sh verify

    # Check available Java VMs
    /usr/libexec/java_home -V

    # Get the current Java home path
    /usr/libexec/java_home

    # Remove the integration if needed
    ./setup_sdkman_java_home.sh uninstall

    # Display help
    ./setup_sdkman_java_home.sh help
    ```

    ## Example Output

    ```bash
    $ ./setup_sdkman_java_home.sh install

    === Installing SDKMAN JDK Integration ===

    ✓ SDKMAN found at /Users/username/.sdkman
    ℹ SDKMAN Current JDK: /Users/username/.sdkman/candidates/java/current
    ℹ Version: 21.0.9
    ℹ Vendor: Amazon Corretto
    ℹ Creating directory structure...
    ✓ Created /Library/Java/JavaVirtualMachines/sdkman-current/Contents
    ✓ Created symlink: /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home -> ~/.sdkman/candidates/java/current
    ✓ Created Info.plist
    ✓ Permissions set

    === Installation Complete ===
    ✓ SDKMAN JDK integration installed successfully

    $ /usr/libexec/java_home -V
    Matching Java Virtual Machines (1):
    9999 (arm64) "Amazon Corretto" - "SDKMAN Current JDK" /Library/Java/JavaVirtualMachines/sdkman-current/Contents/Home
    ```

    ## Commands

    | Command | Description |
    |---------|-------------|
    | `install` | Set up the SDKMAN JDK integration (default command) |
    | `uninstall` | Remove the integration and clean up all created files |
    | `verify` | Verify the setup is working correctly |
    | `help` | Display comprehensive help message |

    ## Files Created

    ```
    /Library/Java/JavaVirtualMachines/sdkman-current/
    ├── Contents/
    │ ├── Home -> ~/.sdkman/candidates/java/current (symlink)
    │ └── Info.plist
    ```

    ## Troubleshooting

    ### SDKMAN not found
    ```bash
    # Install SDKMAN
    curl -s "https://get.sdkman.io" | bash
    source ~/.sdkman/bin/sdkman-init.sh
    ```

    ### No current JDK set
    ```bash
    # Install a JDK
    sdk install java 21.0.9-amzn

    # Or set an existing one as current
    sdk use java 21.0.9-amzn
    ```

    ### Verification fails
    ```bash
    # Run the verify command for detailed diagnostics
    ./setup_sdkman_java_home.sh verify
    ```

    ### Switching JDK versions
    When you switch JDK versions with SDKMAN:
    ```bash
    sdk use java 17.0.9-tem
    ```
    The symlink automatically points to the new version - no need to re-run the script!

    ## Technical Details

    ### Why Version 9999?

    The `JVMPlatformVersion` is set to `9999` in `Info.plist` to ensure this JDK is always selected as the default by `/usr/libexec/java_home`. This is important because:

    - Other manually installed JDKs might exist on the system
    - `/usr/libexec/java_home` selects the highest version by default
    - This ensures SDKMAN's current JDK is always preferred

    ### Supported SDKMAN Vendors

    The script auto-detects these vendors from the JDK path:

    - `amzn` → Amazon Corretto
    - `tem` → Eclipse Temurin
    - `zulu` → Azul Zulu
    - `graal*` → GraalVM
    - `liberica` → BellSoft Liberica
    - `sapmchn` → SAP Machine
    - Others → SDKMAN (vendor-code)

    ## Use Cases

    - **Xcode Projects**: Build phases requiring Java (e.g., Kotlin/Native builds)
    - **Shell Scripts**: Scripts that use `JAVA_HOME=$(/usr/libexec/java_home)`
    - **Development Tools**: IDEs and tools expecting standard macOS Java detection
    - **CI/CD Pipelines**: macOS build environments using SDKMAN

    ## Contributing

    Found a bug or have a suggestion? Feel free to open an issue or submit improvements!

    ## License

    MIT License - feel free to use, modify, and distribute.

    ## Author

    **Abdelraouf Sabri**

    - GitHub: [@abd3lraouf](https://github.com/abd3lraouf)
    - LinkedIn: [abd3lraouf](https://linkedin.com/in/abd3lraouf)

    ## References

    - [SDKMAN Official Site](https://sdkman.io/)
    - [Apple Developer Documentation](https://developer.apple.com/)
    - `/usr/libexec/java_home` - macOS's Java detection utility (largely undocumented)

    ---

    *If this script helped you, consider giving it a ⭐ star!*
    438 changes: 438 additions & 0 deletions setup_sdkman_java_home.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,438 @@
    #!/usr/bin/env bash

    ################################################################################
    # Setup SDKMAN JDK Integration with /usr/libexec/java_home
    ################################################################################
    # This script configures macOS to recognize SDKMAN-installed JDKs through
    # /usr/libexec/java_home by creating a proper directory structure and symlink
    # in /Library/Java/JavaVirtualMachines.
    #
    # Usage:
    # ./setup_sdkman_java_home.sh [install|uninstall|verify|help]
    #
    # Options:
    # install - Set up the SDKMAN JDK integration (default)
    # uninstall - Remove the SDKMAN JDK integration
    # verify - Check if the setup is working correctly
    # help - Display this help message
    #
    # Requirements:
    # - macOS
    # - SDKMAN installed with at least one JDK
    # - sudo privileges
    ################################################################################

    set -euo pipefail

    # Constants
    readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
    readonly SCRIPT_VERSION="1.0.0"
    readonly TARGET_DIR="/Library/Java/JavaVirtualMachines/sdkman-current"
    readonly CONTENTS_DIR="${TARGET_DIR}/Contents"
    readonly HOME_LINK="${CONTENTS_DIR}/Home"
    readonly PLIST_FILE="${CONTENTS_DIR}/Info.plist"

    # Colors for output
    readonly RED='\033[0;31m'
    readonly GREEN='\033[0;32m'
    readonly YELLOW='\033[1;33m'
    readonly BLUE='\033[0;34m'
    readonly BOLD='\033[1m'
    readonly NC='\033[0m' # No Color

    # Cleanup on error
    cleanup() {
    local exit_code=$?
    if [ $exit_code -ne 0 ]; then
    error "Script failed with exit code $exit_code"
    fi
    }

    trap cleanup EXIT

    ################################################################################
    # Utility Functions
    ################################################################################

    # Print colored messages
    print_header() {
    echo -e "\n${BOLD}${BLUE}===${NC} ${BOLD}$1${NC} ${BOLD}${BLUE}===${NC}\n"
    }

    success() {
    echo -e "${GREEN}${NC} $1"
    }

    info() {
    echo -e "${BLUE}${NC} $1"
    }

    warn() {
    echo -e "${YELLOW}${NC} $1"
    }

    error() {
    echo -e "${RED}${NC} $1" >&2
    }

    # Check if running on macOS
    check_macos() {
    if [[ "$(uname -s)" != "Darwin" ]]; then
    error "This script only works on macOS"
    exit 1
    fi
    }

    # Check if SDKMAN is installed
    check_sdkman() {
    local sdkman_dir="${SDKMAN_DIR:-$HOME/.sdkman}"

    if [[ ! -d "$sdkman_dir" ]]; then
    error "SDKMAN not found at $sdkman_dir"
    info "Install SDKMAN from: https://sdkman.io/install"
    exit 1
    fi

    success "SDKMAN found at $sdkman_dir"
    }

    # Get SDKMAN current JDK path
    get_sdkman_current_jdk() {
    local sdkman_dir="${SDKMAN_DIR:-$HOME/.sdkman}"
    local current_jdk="${sdkman_dir}/candidates/java/current"

    if [[ ! -e "$current_jdk" ]]; then
    error "No current JDK set in SDKMAN"
    info "Install a JDK with: sdk install java"
    info "Or set current with: sdk use java <version>"
    exit 1
    fi

    # Resolve symlink to get actual JDK path
    local actual_jdk
    actual_jdk="$(readlink "$current_jdk" 2>/dev/null || echo "$current_jdk")"

    echo "$current_jdk"
    }

    # Get JDK version from SDKMAN
    get_jdk_version() {
    local jdk_path="$1"

    # Source SDKMAN and get current version
    local sdkman_init="${SDKMAN_DIR:-$HOME/.sdkman}/bin/sdkman-init.sh"
    if [[ -f "$sdkman_init" ]]; then
    # shellcheck source=/dev/null
    source "$sdkman_init" 2>/dev/null || true
    local version
    version="$(sdk current java 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+[^[:space:]]*' || echo "unknown")"
    echo "$version"
    else
    echo "unknown"
    fi
    }

    # Get JDK vendor from path
    get_jdk_vendor() {
    local jdk_path="$1"
    local vendor="SDKMAN"

    # Extract vendor from path if possible (e.g., 21.0.9-amzn -> Amazon)
    if [[ "$jdk_path" =~ -([a-z]+)$ ]]; then
    local vendor_code="${BASH_REMATCH[1]}"
    case "$vendor_code" in
    amzn) vendor="Amazon Corretto" ;;
    tem) vendor="Eclipse Temurin" ;;
    zulu) vendor="Azul Zulu" ;;
    graal*) vendor="GraalVM" ;;
    liberica) vendor="BellSoft Liberica" ;;
    sapmchn) vendor="SAP Machine" ;;
    *) vendor="SDKMAN ($vendor_code)" ;;
    esac
    fi

    echo "$vendor"
    }

    # Check if setup already exists
    check_existing_setup() {
    [[ -d "$TARGET_DIR" ]]
    }

    # Verify sudo access
    verify_sudo() {
    if ! sudo -v; then
    error "Sudo privileges required"
    exit 1
    fi

    # Keep sudo alive
    while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null &
    }

    ################################################################################
    # Installation Functions
    ################################################################################

    install_setup() {
    print_header "Installing SDKMAN JDK Integration"

    # Get SDKMAN JDK path
    local sdkman_jdk
    sdkman_jdk="$(get_sdkman_current_jdk)"
    local jdk_version
    jdk_version="$(get_jdk_version "$sdkman_jdk")"
    local jdk_vendor
    jdk_vendor="$(get_jdk_vendor "$sdkman_jdk")"

    info "SDKMAN Current JDK: $sdkman_jdk"
    info "Version: $jdk_version"
    info "Vendor: $jdk_vendor"

    # Check for existing setup
    if check_existing_setup; then
    warn "Existing setup found at $TARGET_DIR"
    read -rp "Remove and reinstall? (y/N): " response
    if [[ "$response" =~ ^[Yy]$ ]]; then
    uninstall_setup
    else
    info "Installation cancelled"
    exit 0
    fi
    fi

    # Request sudo access
    verify_sudo

    # Create directory structure
    info "Creating directory structure..."
    sudo mkdir -p "$CONTENTS_DIR"
    success "Created $CONTENTS_DIR"

    # Create symlink
    info "Creating symlink to SDKMAN JDK..."
    sudo ln -sf "$sdkman_jdk" "$HOME_LINK"
    success "Created symlink: $HOME_LINK -> $sdkman_jdk"

    # Create Info.plist
    info "Creating Info.plist..."
    sudo tee "$PLIST_FILE" > /dev/null << EOF
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    <key>CFBundleIdentifier</key>
    <string>sdkman.current</string>
    <key>CFBundleName</key>
    <string>SDKMAN Current JDK</string>
    <key>CFBundleVersion</key>
    <string>${jdk_version}</string>
    <key>JavaVM</key>
    <dict>
    <key>JVMPlatformVersion</key>
    <string>9999</string>
    <key>JVMVendor</key>
    <string>${jdk_vendor}</string>
    <key>JVMVersion</key>
    <string>9999</string>
    </dict>
    </dict>
    </plist>
    EOF
    success "Created Info.plist"

    # Set proper permissions
    info "Setting permissions..."
    sudo chmod -R 755 "$TARGET_DIR"
    success "Permissions set"

    print_header "Installation Complete"
    success "SDKMAN JDK integration installed successfully"

    # Verify installation
    verify_setup
    }

    ################################################################################
    # Uninstallation Functions
    ################################################################################

    uninstall_setup() {
    print_header "Uninstalling SDKMAN JDK Integration"

    if ! check_existing_setup; then
    warn "No existing setup found at $TARGET_DIR"
    info "Nothing to uninstall"
    return 0
    fi

    # Request sudo access if not already verified
    verify_sudo

    info "Removing $TARGET_DIR..."
    sudo rm -rf "$TARGET_DIR"
    success "Removed SDKMAN JDK integration"

    print_header "Uninstallation Complete"
    }

    ################################################################################
    # Verification Functions
    ################################################################################

    verify_setup() {
    print_header "Verifying Setup"

    # Check if setup exists
    if ! check_existing_setup; then
    error "Setup not found at $TARGET_DIR"
    info "Run with 'install' to set up the integration"
    exit 1
    fi

    # Check symlink
    if [[ ! -L "$HOME_LINK" ]]; then
    error "Symlink not found at $HOME_LINK"
    exit 1
    fi
    success "Symlink exists: $HOME_LINK"

    # Check if symlink target exists
    if [[ ! -e "$HOME_LINK" ]]; then
    error "Symlink target does not exist"
    local target
    target="$(readlink "$HOME_LINK")"
    error "Broken symlink: $HOME_LINK -> $target"
    exit 1
    fi
    local symlink_target
    symlink_target="$(readlink "$HOME_LINK")"
    success "Symlink target valid: $symlink_target"

    # Check Info.plist
    if [[ ! -f "$PLIST_FILE" ]]; then
    error "Info.plist not found at $PLIST_FILE"
    exit 1
    fi
    success "Info.plist exists"

    # Test /usr/libexec/java_home
    info "Testing /usr/libexec/java_home..."
    local java_home_output
    if java_home_output=$(/usr/libexec/java_home 2>&1); then
    success "/usr/libexec/java_home works"
    echo -e "\n${BOLD}Output:${NC}"
    echo "$java_home_output"
    else
    error "/usr/libexec/java_home failed"
    echo "$java_home_output"
    exit 1
    fi

    # Show all available JVMs
    echo -e "\n${BOLD}Available Java Virtual Machines:${NC}"
    /usr/libexec/java_home -V 2>&1 || true

    print_header "Verification Complete"
    success "Setup is working correctly"

    echo
    info "Notes:"
    echo " • When you change JDK with 'sdk use java <version>', the symlink"
    echo " will automatically point to the new current version"
    echo " • Xcode and other tools can now find Java using /usr/libexec/java_home"
    echo " • The version is set to 9999 to ensure this JDK is always selected"
    }

    ################################################################################
    # Help Function
    ################################################################################

    show_help() {
    cat << EOF
    ${BOLD}${SCRIPT_NAME}${NC} - Version ${SCRIPT_VERSION}
    ${BOLD}DESCRIPTION${NC}
    Configure macOS to recognize SDKMAN-installed JDKs through /usr/libexec/java_home
    by creating a proper directory structure in /Library/Java/JavaVirtualMachines.
    ${BOLD}USAGE${NC}
    ${SCRIPT_NAME} [COMMAND]
    ${BOLD}COMMANDS${NC}
    install Set up the SDKMAN JDK integration (default)
    uninstall Remove the SDKMAN JDK integration
    verify Verify the setup is working correctly
    help Display this help message
    ${BOLD}EXAMPLES${NC}
    # Install the integration
    ${SCRIPT_NAME} install
    # Verify it's working
    ${SCRIPT_NAME} verify
    # Remove the integration
    ${SCRIPT_NAME} uninstall
    ${BOLD}HOW IT WORKS${NC}
    1. Creates /Library/Java/JavaVirtualMachines/sdkman-current/Contents/
    2. Symlinks Contents/Home to SDKMAN's current JDK
    3. Creates Info.plist with proper metadata
    4. Sets version to 9999 to ensure it's always selected
    ${BOLD}REQUIREMENTS${NC}
    - macOS
    - SDKMAN installed with at least one JDK
    - sudo privileges
    ${BOLD}FILES CREATED${NC}
    ${TARGET_DIR}/
    ${CONTENTS_DIR}/
    ${HOME_LINK} (symlink)
    ${PLIST_FILE}
    ${BOLD}MORE INFO${NC}
    - SDKMAN: https://sdkman.io/
    - Report issues: https://github.com/anthropics/claude-code/issues
    EOF
    }

    ################################################################################
    # Main Function
    ################################################################################

    main() {
    # Check prerequisites
    check_macos

    # Parse command
    local command="${1:-install}"

    case "$command" in
    install)
    check_sdkman
    install_setup
    ;;
    uninstall)
    uninstall_setup
    ;;
    verify)
    check_sdkman
    verify_setup
    ;;
    help|--help|-h)
    show_help
    ;;
    *)
    error "Unknown command: $command"
    echo
    show_help
    exit 1
    ;;
    esac
    }

    # Run main function
    main "$@"