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.
/usr/libexec/java_home is macOS's standard way to locate Java installations, but it doesn't recognize SDKMAN-installed JDKs because:
- SDKMAN-installed JDKs don't follow the standard macOS JDK structure
- They're not located in
/Library/Java/JavaVirtualMachineswhere macOS expects them
This causes issues with:
- Xcode build phases that require Java
- Tools relying on
JAVA_HOMEfrom/usr/libexec/java_home - Shell scripts expecting standard Java detection
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.
- Creates
/Library/Java/JavaVirtualMachines/sdkman-current/Contents/ - Symlinks
Contents/Hometo SDKMAN's current JDK (~/.sdkman/candidates/java/current) - Generates
Info.plistwith proper metadata (version set to 9999 to ensure it's always selected) - Automatically tracks SDKMAN's current JDK - when you switch versions with
sdk use java <version>, the symlink follows
- ✅ 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
- macOS (Darwin)
- SDKMAN installed with at least one JDK
- sudo privileges (required to write to
/Library/Java/JavaVirtualMachines)
# 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# 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$ ./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| 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 |
/Library/Java/JavaVirtualMachines/sdkman-current/
├── Contents/
│ ├── Home -> ~/.sdkman/candidates/java/current (symlink)
│ └── Info.plist
# Install SDKMAN
curl -s "https://get.sdkman.io" | bash
source ~/.sdkman/bin/sdkman-init.sh# Install a JDK
sdk install java 21.0.9-amzn
# Or set an existing one as current
sdk use java 21.0.9-amzn# Run the verify command for detailed diagnostics
./setup_sdkman_java_home.sh verifyWhen you switch JDK versions with SDKMAN:
sdk use java 17.0.9-temThe symlink automatically points to the new version - no need to re-run the script!
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_homeselects the highest version by default- This ensures SDKMAN's current JDK is always preferred
The script auto-detects these vendors from the JDK path:
amzn→ Amazon Correttotem→ Eclipse Temurinzulu→ Azul Zulugraal*→ GraalVMliberica→ BellSoft Libericasapmchn→ SAP Machine- Others → SDKMAN (vendor-code)
- 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
Found a bug or have a suggestion? Feel free to open an issue or submit improvements!
MIT License - feel free to use, modify, and distribute.
Abdelraouf Sabri
- GitHub: @abd3lraouf
- LinkedIn: abd3lraouf
- SDKMAN Official Site
- Apple Developer Documentation
/usr/libexec/java_home- macOS's Java detection utility (largely undocumented)
If this script helped you, consider giving it a ⭐ star!