Java

There is no AI here. All content is human-authored and tested for accuracy.

Install SDKMAN for Java on Mac

Install SDKMAN on Mac to change Java versions easily. Use the Java version manager to switch JDK versions globally and per project.

The Java version manager SDKMAN, or Software Development Kit Manager, is a command-line tool that installs, manages, and switches among multiple Java versions on macOS. This guide covers installing SDKMAN on Macs, managing Java versions, and configuring project-specific environments.

My main article, Java Version Managers on Mac, offers recommendations based on use case, and comparisons, among SDKMAN and other Java version managers. SDKMAN is preferred by developers who only use Java; developers who use multiple languages should consider mise instead.

Before you get started

You'll need a terminal application to use SDKMAN and develop with Java. Apple includes the Mac terminal but I prefer Warp Terminal. Warp is an easy-to-use terminal application, with AI assistance to help you learn and remember terminal commands. Download Warp Terminal now; it's FREE and makes coding easier when working with Java.

Why Use SDKMAN

SDKMAN handles a complete Java version management workflow. Unlike Homebrew (which installs JDKs but doesn't switch between them) or jenv (which switches but doesn't install), SDKMAN does both. Here's what makes it useful for developers:

  • One-command installation — Install any JDK with sdk install java
  • Instant version switching — Set a default or change Java versions per session
  • Multiple vendors — Use JDKs from Temurin, Zulu, Corretto, GraalVM, and other vendors
  • Automatic JAVA_HOME — No manual editing of Java environment variables
  • Project-specific versions — Use .sdkmanrc files to lock versions per project
  • Unified tool management — Also manages Maven, Gradle, Kotlin, and 80+ other tools

SDKMAN originated as GVM (Groovy enVironment Manager) in 2012 before expanding to support the broader JVM ecosystem. The tool runs on macOS, Linux, and Windows WSL.

SDKMAN vs Homebrew

Use Homebrew for general system tools and packages. Instead of SDKMAN, use jEnv with Homebrew if you just need lightweight switching among Homebrew-installed JDKs. If you want to use SDKMAN for both Java and JVM ecosystem tools, use SDKMAN to install JDKs, not Homebrew. Having Java from both Homebrew and SDKMAN can cause PATH and JAVA_HOME conflicts. Avoid mixing installation methods for the same tools.

Install SDKMAN

The installation uses a single curl command that downloads and runs the official setup script.

Run the Installer

Learn How to Open Terminal in Mac and run:

$ curl -s "https://get.sdkman.io" | bash

The script performs several automated steps:

  1. Verifies prerequisites are available
  2. Creates the ~/.sdkman/ directory structure
  3. Downloads the CLI scripts and native components
  4. Detects your platform (Apple Silicon or Intel)
  5. Adds initialization code to your shell configuration
  6. Fetches the current SDK catalog

Be aware that the SDKMAN installation script automatically modifies your shell configuration files. Look at the end of the .zshrc file to see the changes. The .zshrc file loads after the .zprofile file so it should override any PATH settings in the .zprofile file, but to avoid confusion, comment out any PATH settings in the .zprofile file.

You'll either need to restart your terminal or reload your .zshrc file by entering source ~/.zshrc.

Verify Installation

Confirm SDKMAN installed successfully:

$ sdk version

You should see output showing both script and native versions:

SDKMAN!
script: 5.20.0
native: 0.7.14 (macos aarch64)

The "native" component is written in Rust for improved performance. If you see version numbers, SDKMAN is ready to use.

What Changed in Your Shell Configuration

The installer added this snippet at the end of your .zshrc file (or ~/.bash_profile for Bash):

#THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!!
export SDKMAN_DIR="$HOME/.sdkman"
[[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]] && source "$HOME/.sdkman/bin/sdkman-init.sh"

To use SDKMAN, keep this snippet at the end of your shell configuration file. Moving it can cause initialization failures.

SDKMAN Directory Structure

SDKMAN installs to ~/.sdkman with this structure:

~/.sdkman/
├── archives/         # Cached downloaded archives
├── bin/              # Shell scripts including sdkman-init.sh
├── candidates/       # Installed SDKs
│   ├── java/
│   │   ├── 25.0.1-tem/
│   │   └── current -> 25.0.1-tem
│   ├── maven/
│   └── gradle/
├── etc/
│   └── config        # Configuration file
└── tmp/              # Temporary files

The candidates/java/current symlink points to your active Java version. SDKMAN updates this symlink when you switch versions.

Install Your First JDK

With SDKMAN installed, you can now install Java.

List Available Java Versions

View all available JDKs:

$ sdk list java

The output displays a table organized by vendor:

================================================================================
Available Java Versions for macOS ARM 64bit
================================================================================
 Vendor        | Use | Version      | Dist    | Status     | Identifier
--
 Corretto      |     | 25.0.1       | amzn    |            | 25.0.1-amzn 
 .
 .
 .

Enter q to exit the list.

Understand the List Output

Each column tells you something important:

  • Vendor — The distribution provider (Temurin, Zulu, Corretto, etc.)
  • Use — Shows >>> for the currently active version
  • Version — The semantic version number
  • Dist — Vendor short code used in identifiers
  • Status — Shows installed for versions on your system
  • Identifier — The string you'll use with sdk install and other commands

Status markers to know:

  • >>> — Currently active version
  • * — Installed but not active
  • Blank — Available for download

Choose a JDK Vendor

SDKMAN provides access to JDKs from many vendors. Here's what to know about the most common ones:

  • -tem – Eclipse Temurin, best for general development (recommended)
  • -zulu – Azul Zulu, good for Java 8 or 11 on Apple Silicon
  • -amzn – Amazon Corretto, best for AWS deployments
  • -oracle – Oracle JDK, best for Oracle-specific features (check license)
  • -graalce – GraalVM CE, best for native compilation, high performance
  • -librca – BellSoft Liberica, best for Spring Boot, includes JavaFX
  • -ms – Microsoft OpenJDK, best for Azure deployments
  • -sapmchn – SAP SapMachine, best for SAP environments

Recommendation: For most developers, Eclipse Temurin (-tem) is the best choice. It's TCK-certified (meaning it passed Oracle's compatibility tests) and has no commercial license restrictions.

Install Java

Install the latest Temurin Java 25 LTS:

$ sdk install java 25.0.1-tem

SDKMAN downloads the JDK. The first JDK you install will be set as a default automatically. Subsequent JDK installs will show a prompt asking whether to set it as your default.

To install the latest version without specifying an identifier:

$ sdk install java

This installs the latest LTS release from the default vendor (currently Temurin).

Verify Java Installation

Confirm Java installed correctly:

$ java -version

The java command works immediately after installation with zero configuration. That's because SDKMAN already modified your .zshrc file to adjust PATH so that ~/.sdkman/candidates/java/current/bin comes before other Java locations, and sets the right environment variables. SDKMAN does not, by default, create or rely on JDK bundles in /Library/Java/JavaVirtualMachines, and it doesn’t depend on macOS’s /usr/bin/java system launcher for its behavior.

You should see output mentioning Temurin and Java 25. Also verify the path:

$ which java

The output should show ~/.sdkman/candidates/java/current/bin/java.

Manage Multiple Java Versions

Real-world development often requires multiple Java versions. One project might need Java 25 while another requires Java 17. SDKMAN makes switching between them easy.

Install Additional Versions

Install Java 17 alongside your existing Java 25:

$ sdk install java 17.0.13-tem

You can install as many versions as you need. They coexist peacefully in separate directories.

Check Installed Versions

See which versions you have installed:

$ sdk list java

Look for entries marked with installed in the Status column or * in the Use column. Enter q to exit the list.

Check Current Version

See which Java version is currently active:

$ sdk current java
Using java version 25.0.1-tem

Or check all active SDKs at once:

$ sdk current
Current versions in use:
java 25.0.1-tem

Switch Versions Temporarily

Use sdk use to change the Java version for your current terminal session only:

$ sdk use java 17.0.13-tem

Output confirms the switch:

Using java version 17.0.13-tem in this shell.

This change only affects your current terminal window. Other terminals and future sessions use your default version. This is useful when testing compatibility without changing your system-wide setting.

Set a Permanent Default

Use sdk default to change the Java version for all new terminal sessions:

$ sdk default java 25.0.1-tem
setting java 25.0.1-tem as the default version for all shells.

This updates the current symlink in ~/.sdkman/candidates/java/ and affects all future terminals.

Uninstall a Version

Remove a JDK you no longer need:

$ sdk uninstall java 17.0.8-tem

This deletes the version directory and frees disk space.

Configure Project-Specific Java

Different projects often require different Java versions. The .sdkmanrc file lets you declare which version a project needs. SDKMAN will switch automatically when you enter the project directory.

Create a .sdkmanrc File

Navigate to your project root and generate the configuration file:

$ cd /path/to/your-project
$ sdk env init
.sdkmanrc created.

This creates .sdkmanrc with your currently active versions:

cat .sdkmanrc
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=25.0.1-tem

Edit for Your Project's Needs

Open .sdkmanrc in your editor and adjust the version if you wish.

java=17.0.13-tem

You can also specify multiple SDKs:

java=17.0.13-tem
maven=3.9.6
gradle=8.5

Apply the Configuration

Activate the project's SDK versions manually:

$ sdk env

SDKMAN switches to the versions specified in .sdkmanrc.

If SDKs in the file aren't installed yet:

$ sdk env install

This installs any missing SDKs, then activates them.

To reset to your default versions:

$ sdk env clear
Restored java version to 25.0.1-tem (default)

Enable Automatic Switching

Configure SDKMAN to apply .sdkmanrc automatically when you enter a directory.

Open the SDKMAN configuration:

$ sdk config

This opens the config file in your default editor. Find or add this line:

sdkman_auto_env=true

Save and close. Now when you cd into a directory containing .sdkmanrc, SDKMAN automatically switches to those versions. Leaving the directory restores your defaults.

Limitation: The .sdkmanrc file must be in the current directory. SDKMAN does not search parent directories. If you're in a subdirectory, navigate to the project root or run sdk env manually.

Commit to Version Control

Share the configuration with your team:

$ git add .sdkmanrc
$ git commit -m "Add SDKMAN configuration for Java 25"

When teammates clone the repository and run sdk env install, they get the exact same SDK versions. This eliminates "works on my machine" problems.

Configure SDKMAN

SDKMAN's behavior is controlled by a configuration file at ~/.sdkman/etc/config.

Key SDKMAN Configuration Options

  • sdkman_auto_env – Default: false, auto-switch versions when entering directories with .sdkmanrc
  • sdkman_auto_answer – Default: false, skip confirmation prompts (useful for CI)
  • sdkman_auto_complete – Default: true, enable tab completion
  • sdkman_selfupdate_feature – Default: true, check for SDKMAN updates
  • sdkman_colour_enable – Default: true, enable colored terminal output
  • sdkman_curl_connect_timeout – Default: 7, connection timeout in seconds
  • sdkman_curl_max_time – Default: 10, maximum time for curl operations

Recommended Settings

For daily development, enable automatic environment switching:

sdkman_auto_env=true
sdkman_auto_complete=true

If you experience slow or unstable network connections, increase timeouts:

sdkman_curl_connect_timeout=30
sdkman_curl_max_time=60

Manage Other JVM Tools

SDKMAN manages 80+ SDK tools ("candidates") beyond Java. The same commands work for all of them.

Install Build Tools

Install Maven and Gradle:

$ sdk install maven 3.9.6
$ sdk install gradle 8.5

Install JVM Languages

Install Kotlin, Scala, or Groovy:

$ sdk install kotlin
$ sdk install scala
$ sdk install groovy

Install Frameworks

Install Spring Boot CLI or other frameworks:

$ sdk install springboot
$ sdk install quarkus
$ sdk install micronaut

List All Candidates

View all available SDK categories:

$ sdk list

Pin Tools in .sdkmanrc

Include multiple tools in the .sdkmanrc project configuration file:

java=25.0.1-tem
maven=3.9.6
gradle=8.5

Work Offline

SDKMAN can operate without internet connectivity using cached SDKs.

Enable Offline Mode

Switch to offline mode:

$ sdk offline enable

In offline mode, commands requiring downloads fail, but queries like sdk list and sdk current work with cached data. This is useful when traveling or working in environments with restricted network access.

Disable Offline Mode

Return to online mode:

$ sdk offline disable

SDKMAN auto-enables offline mode when it detects no connectivity and returns to online mode when connectivity is restored.

Maintain Your Installation

Keep SDKMAN and your SDKs up to date with these maintenance commands.

Update SDKMAN Itself

Check for and install SDKMAN CLI updates:

$ sdk selfupdate

Force reinstall even if current:

$ sdk selfupdate force

Refresh the SDK Catalog

Update the list of available SDK versions:

$ sdk update

Run this when a newly released Java version doesn't appear in sdk list java.

Upgrade Installed SDKs

Upgrade a candidate to its latest version:

$ sdk upgrade java

This is different from sdk update. The update command refreshes the catalog; upgrade actually installs newer versions of SDKs you already have.

Clear Caches

SDKMAN caches downloaded archives. Clear them to free disk space:

$ sdk flush archives

Other flush options:

  • sdk flush tmp — Clear temporary files
  • sdk flush broadcast — Clear broadcast messages
  • sdk flush — Clear everything

Never manually delete ~/.sdkman/tmp/. Always use sdk flush to preserve SDKMAN's state.

Troubleshoot Common Issues

Here are solutions to problems you might encounter.

"sdk: command not found"

Cause: The shell initialization script hasn't been sourced.

Solutions:

  1. Open a new terminal window
  2. Or source manually:
    $ source "$HOME/.sdkman/bin/sdkman-init.sh"
    
  3. Verify ~/.zshrc contains the SDKMAN initialization snippet at the end of the file

Missing zip or unzip During Installation

Error: Installation fails with message about missing zip or unzip.

Solution: Install the missing utilities:

$ xcode-select --install

Or via Homebrew:

$ brew install zip unzip

"command not found: __sdkman_echo_debug"

Cause: Zsh parsing issue, often from conflicting shell configurations.

Solutions:

  1. Check for syntax errors in ~/.zshrc
  2. Ensure /usr/bin/find is being used
  3. Reinstall SDKMAN:
    $ curl -sL "https://get.sdkman.io" | bash
    

Wrong Java Version Active

Symptom: sdk current java doesn't match java -version.

Solutions:

  1. Ensure you ran sdk use or sdk default
  2. Check for conflicting JAVA_HOME:
    $ echo $JAVA_HOME
    
  3. Verify no other Java installation is overriding PATH:
    $ which -a java
    

Look for Java installations from Homebrew, Oracle installers, or system paths that might take precedence.

Network or SSL Errors

Cause: Firewall blocking connections or network instability.

Solutions:

  1. Enable offline mode if you have cached SDKs:
    $ sdk offline enable
    
  2. Increase timeout values in ~/.sdkman/etc/config:
    sdkman_curl_connect_timeout=30
    sdkman_curl_max_time=60
    

New Java Version Not Listed

Symptom: A newly released Java version doesn't appear in sdk list java.

Solution: Refresh the candidate cache:

$ sdk update

Command Reference

Here's a quick reference for the most common SDKMAN commands.

Installing and Removing Java with SDKMAN

  • sdk install java 25.0.1-tem – Install specific version
  • sdk install java – Install latest version
  • sdk uninstall java 25.0.1-tem – Remove installed version

Listing and Information

  • sdk list java – List available Java versions
  • sdk list – List all available SDK candidates
  • sdk current java – Show active Java version
  • sdk current – Show all active SDKs
  • sdk home java 25.0.1-tem – Get installation path
  • sdk version – Show SDKMAN version

Version Switching

  • sdk use java 25.0.1-tem – Switch for current shell only
  • sdk default java 25.0.1-tem – Set permanent default
  • sdk upgrade java – Upgrade to latest version

Project Configuration

  • sdk env init – Create .sdkmanrc
  • sdk env – Apply .sdkmanrc versions
  • sdk env install – Install missing SDKs from .sdkmanrc
  • sdk env clear – Reset to default versions

Maintenance

  • sdk selfupdate – Update SDKMAN
  • sdk update – Refresh SDK catalog
  • sdk flush – Clear all caches
  • sdk flush archives – Clear downloaded archives
  • sdk config – Open configuration in editor
  • sdk offline enable – Enable offline mode
  • sdk offline disable – Disable offline mode

Additional Notes

You may want to use SDKMAN with Oh My Zsh, the open‑source, community‑driven framework for managing and extending your Zsh configuration. Or you may need to use SDKMAN with a CI/CD automated pipeline.

Oh-My-Zsh Integration

If you use Oh-My-Zsh, enable SDKMAN's auto-completion plugin by adding sdk to your plugins list in ~/.zshrc:

plugins=(git docker sdk)

Reload your shell:

$ source ~/.zshrc

CI/CD Installation

For automated pipelines, SDKMAN supports special installation parameters:

Skip shell configuration modification:

$ curl -s "https://get.sdkman.io?rcupdate=false" | bash

Fully non-interactive installation:

$ curl -s "https://get.sdkman.io?ci=true" | bash

Combined for CI pipelines:

$ curl -s "https://get.sdkman.io?rcupdate=false&ci=true" | bash

The ci=true parameter enables auto-answer mode and disables colored output.

Uninstall SDKMAN

If you need to remove SDKMAN entirely:

  1. Optional: Backup your configuration

    $ tar zcvf ~/sdkman-backup.tar.gz -C ~/ .sdkman
    
  2. Remove the SDKMAN directory

    $ rm -rf ~/.sdkman
    
  3. Edit shell configuration

    Remove these lines from ~/.zshrc (or ~/.bash_profile):

    export SDKMAN_DIR="$HOME/.sdkman"
    [[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]] && source "$HOME/.sdkman/bin/sdkman-init.sh"
    

To remove Java installations that were made outside of SDKMAN, see Uninstall Java on Mac.

What's Next

You now have SDKMAN installed and configured for Java development on your Mac. Here are some next steps:

  • Explore other SDKs — Run sdk list to see all available candidates
  • Set up your IDE — Configure IntelliJ, VS Code, or Eclipse to use SDKMAN JDKs
  • Add .sdkmanrc to projects — Lock Java versions for consistent team environments
  • Enable auto-env — Set sdkman_auto_env=true for seamless project switching

For more information, visit the official SDKMAN documentation at sdkman.io. To understand how JAVA_HOME works with manual configuration, see Set JAVA_HOME on Mac.

My mac.install.guide is a trusted source of installation guides for professional developers. Take a look at the Mac Install Guide home page for tips and trends and see what to install next.