Mastering SDKMAN!
⚡ Modern JVM Tooling: SDKMAN! (Software Development Kit Manager) is a lightweight, open-source CLI tool for managing parallel versions of multiple Software Development Kits across Unix-like systems (macOS, Linux, and Windows via WSL/Git Bash). By managing
JAVA_HOME,PATH, and build tool binaries entirely in user-space, SDKMAN! eliminates environment pollution and version friction.
1. Why SDKMAN!? The Multi-Runtime Challenge
Modern backend engineering frequently requires juggling incompatible SDK versions across legacy and greenfield projects:
- Project A requires Java 8 and Maven 3.6.
- Project B requires Java 17 (LTS) and Gradle 7.6.
- Project C requires Java 21 (LTS) or preview builds of Java 25, Kotlin 2.0, and Micronaut.
Manually downloading tarballs, untarring them into /Library/Java/ or /opt/, and manually updating .zshrc / .bashrc environment variables is brittle and error-prone.
SDKMAN! solves this by providing a unified, declarative package manager for JVM and cloud-native toolchains that operates completely in user-space (~/.sdkman) without requiring sudo privileges.
2. Core Architecture & The Symlink Engine
SDKMAN! uses a deterministic directory layout and dynamic filesystem symlinks to switch active toolchains instantly.
~/.sdkman/
├── bin/ # SDKMAN! shell entry scripts & Rust native binary
├── candidates/ # Installed SDK binaries
│ ├── java/
│ │ ├── 17.0.12-tem/ # Eclipse Temurin JDK 17
│ │ ├── 21.0.4-tem/ # Eclipse Temurin JDK 21
│ │ └── current ────> symlink to active version (e.g. 21.0.4-tem)
│ ├── gradle/
│ │ ├── 8.5/
│ │ └── current ────> symlink to active version
│ └── maven/
│ ├── 3.9.9/
│ └── current ────> symlink to active version
└── etc/
└── config # Global configuration settings +-------------------------------------------------------------------------+
| Terminal Shell (zsh / bash) |
+-------------------------------------------------------------------------+
│
Intercepts command or `sdk use`
│
v
+-------------------------------------------------------------------------+
| SDKMAN! Environment Engine |
| 1. Updates `JAVA_HOME` ──> ~/.sdkman/candidates/java/current |
| 2. Prepend active binary paths to `$PATH` in memory |
| 3. Updates dynamic symlink pointers |
+-------------------------------------------------------------------------+ Key Architectural Advantages
- Zero Sudo / User Space: All binaries reside in
$HOME/.sdkman/candidates/, preventing permission conflicts and keeping the root OS filesystem clean. - Instant In-Memory Switching (
sdk use): Switches the runtime for the current shell session only, allowing two terminal tabs to run completely different JDK versions simultaneously. - Global Persistence (
sdk default): Updates thecurrentsymlink to establish system-wide defaults for new shell windows. - Rust-Powered High-Performance Core: Integrates native Rust components for ultra-fast candidate resolution, metadata parsing, and network downloads.
3. Installation & Verification
Standard Installation
Open your terminal on macOS, Linux, or WSL and run:
# 1. Download and run the official installer script
curl -s "https://get.sdkman.io" | bash
# 2. Source the initialization snippet into your current shell
source "$HOME/.sdkman/bin/sdkman-init.sh"
# 3. Verify successful installation
sdk version Prerequisites
SDKMAN! requires standard POSIX utilities: curl, zip, unzip, tar, and sed. On minimal Linux/Docker images:
# Debian / Ubuntu
sudo apt-get update && sudo apt-get install -y curl zip unzip
# RHEL / Fedora / AlmaLinux
sudo dnf install -y curl zip unzip 4. Daily CLI Mastery: Essential Candidate Workflows
In SDKMAN! terminology, an SDK (like Java, Kotlin, Maven, Gradle, or Scala) is called a Candidate.
4.1 Discovering Available Candidates & Versions
# List all supported toolchains (Java, Gradle, Maven, Kotlin, Scala, Quarkus, etc.)
sdk list
# List all available distributions and versions for Java
sdk list java
# List available versions for build tools
sdk list gradle
sdk list maven 4.2 Installing SDKs
SDKMAN! supports all major OpenJDK distributions (Temurin, Corretto, GraalVM, Liberica, Microsoft, Oracle, Zulu, Semeru):
# Install Eclipse Temurin JDK 21 (LTS)
sdk install java 21.0.4-tem
# Install Amazon Corretto JDK 17
sdk install java 17.0.12-amzn
# Install GraalVM for native compilation
sdk install java 21.0.2-graal
# Install latest stable Gradle and Maven
sdk install gradle
sdk install maven 3.9.9 4.3 Switching Versions: Session vs Global Default
# Set a GLOBAL default version (persists across all new terminal windows)
sdk default java 21.0.4-tem
# Switch version TEMPORARILY in the current shell session only
sdk use java 17.0.12-amzn
# Check currently active versions
sdk current
sdk current java 4.4 Maintenance & Cleanup
# Uninstall a specific version
sdk uninstall java 11.0.2-open
# Clear downloaded zip archives and temporary files to free disk space
sdk flush archives
sdk flush temp
# Check health and sync with upstream metadata broker
sdk update 5. Project-Level Environments (.sdkmanrc & Auto-Env)
Instead of relying on team members to manually remember which JDK or Gradle version a project needs, SDKMAN! provides declarative project configuration through .sdkmanrc files.
5.1 Creating a Project Configuration
Navigate to your project repository root:
# Generate a .sdkmanrc file with your current active toolchain
sdk env init This generates a .sdkmanrc file:
# .sdkmanrc
java=21.0.4-tem
gradle=8.10
maven=3.9.9 5.2 Activating the Environment
When a developer clones your repo:
# Install any missing SDKs declared in .sdkmanrc
sdk env install
# Activate the declared versions for the current shell
sdk env 5.3 Enabling Automatic Directory Switching (auto-env)
You can configure SDKMAN! to automatically switch versions whenever you cd into a directory containing a .sdkmanrc:
- Open
~/.sdkman/etc/config:nano "$HOME/.sdkman/etc/config" - Enable automatic environment hooks:
sdkman_auto_env=true sdkman_auto_answer=false - Whenever you navigate into a project folder, SDKMAN! silently sets
JAVA_HOMEand$PATHto match the project’s exact requirements!
6. Registering Local & Custom SDK Builds
If you build custom OpenJDK distributions locally, or download proprietary vendor SDKs, you can register them directly with SDKMAN!:
# Syntax: sdk install <candidate> <custom-identifier> <local-path>
sdk install java custom-graalvm /opt/graalvm-ce-java21-21.0.2
# Now use your local build like any standard SDKMAN! candidate
sdk use java custom-graalvm 7. Offline Mode & Air-Gapped Environments
When traveling or working inside secure corporate networks with restricted internet access:
# Enable offline mode (prevents network queries to the SDKMAN! broker)
sdk offline enable
# Work with all locally installed candidates seamlessly
sdk use java 21.0.4-tem
# Re-enable online mode when connected
sdk offline disable 8. Ecosystem Comparison: Version Managers
| Feature | SDKMAN! | jEnv | asdf-vm | Homebrew | WinGet |
|---|---|---|---|---|---|
| Primary Domain | JVM Ecosystem & Cloud Tools | Java JDKs Only | Polyglot (Node, Python, Ruby, etc.) | macOS / Linux General Packages | Windows General Applications |
| Sudo Required | ❌ No (User space) | ❌ No | ❌ No | ❌ No | ⚠️ Windows UAC |
Auto-Env (.rc) | ✅ Built-in (.sdkmanrc) | ✅ (.java-version) | ✅ (.tool-versions) | ❌ No | ❌ No |
| Multi-Vendor JDKs | ✅ 15+ OpenJDK Distributions | ⚠️ Local registration only | ⚠️ Plugin dependent | ⚠️ Limited versions | ⚠️ Vendor MSI packages |
| Build Tools | ✅ Maven, Gradle, SBT, Ant | ❌ No | ✅ Via plugins | ✅ Global only | ⚠️ Global only |
| Local Custom Builds | ✅ First-class (sdk install) | ✅ First-class | ⚠️ Complex | ❌ No | ❌ No |
9. Global Configuration Reference (~/.sdkman/etc/config)
# ~/.sdkman/etc/config
# Automatically switch environment when entering a directory with .sdkmanrc
sdkman_auto_env=true
# Automatically accept prompts during non-interactive scripts
sdkman_auto_answer=false
# Automatically check for SDKMAN! CLI updates
sdkman_selfupdate_feature=true
# Enable native curl / Rust accelerated downloads
sdkman_curl_connect_timeout=7
sdkman_curl_max_time=10 10. Summary & Cheat Sheet
# 🔍 Exploration
sdk list java # Browse all OpenJDK vendors & versions
sdk list # Browse all supported developer candidates
# 📦 Installation & Defaults
sdk install java 21.0.4-tem # Install specific candidate version
sdk default java 21.0.4-tem # Set global default JDK
sdk use java 17.0.12-amzn # Temporary shell-scoped switch
# 📁 Project Environment (.sdkmanrc)
sdk env init # Create .sdkmanrc in current folder
sdk env install # Install missing tools for project
sdk env # Manually load project environment
# 🧹 Maintenance
sdk current # Show active candidates and versions
sdk flush archives # Free up disk space
sdk update # Sync upstream candidate catalogs SDKMAN! is the gold standard for JVM environment orchestration, enabling friction-free development across legacy systems, enterprise LTS releases, and bleeding-edge cloud-native architectures.
Comments & Discussion