SDKMAN!は、Java(JDK)やGradle、Maven、Kotlin、ScalaといったJVM系のSDKを複数バージョン並べて入れ、シェルごとに切り替えるためのコマンドラインツールです。2026年10月8日時点で公式インストーラーが配る安定版は、スクリプト版5.23.2(2026年10月6日公開)とネイティブ版0.7.34です。ネイティブ版はGitHub上に0.7.35のリリースもありますが、インストーラーはまだ0.7.34を入れます。同日にAPIから取得した候補(candidate)一覧は78種類でした。この記事のコマンド出力は、2026年10月8日にmacOS(Intel)の一時ディレクトリへ5.23.2を入れて取得したものです。
まとめ:SDKMAN!を使う前に押さえる要点
- 基本は
sdk install java→sdk use(そのシェルだけ)/sdk default(新しいシェルすべて)の3つ。引数なしのsdk install javaは 25.0.4-tem(Eclipse Temurin 25)を入れる - 2026年3月16日からインストーラーはBash 4未満で止まる。macOS標準の
/bin/bashは3.2なので、| zshで流すかbrew install bashが必要 - Windowsで使えるのはWSL2かGit Bash(zip・unzipの追加が必要)。PowerShellやコマンドプロンプトでは動かず、Cygwinはインストーラーが拒否する
- プロジェクトの版は
.sdkmanrcに書いてGitに含める。CIではactions/setup-java@v6がこのファイルを読み、接尾辞からディストリビューションも判定する - 5.22.5ではチェックサム検証の重大なコマンドインジェクション(GHSA-jh7h-4x3r-f89r)が報告されている。
sdk versionでscriptが5.23.0以上かを確認する - Node.jsやPythonも同じツールでそろえたいならmise。SDKMAN!はJVM以外のツールを候補に入れない方針を公式に明言している
SDKMAN!の仕組みと対応範囲
SDKMAN!は、~/.sdkman/candidates/<候補名>/<バージョン> にSDKを展開し、既定版を指す current というシンボリックリンクを置きます。シェル起動時に読み込まれる sdkman-init.sh が各候補の current/bin をPATHに足し、JAVA_HOME を ~/.sdkman/candidates/java/current に設定します。sdk use で切り替えると、そのシェルの JAVA_HOME とPATHだけが特定バージョンのディレクトリへ書き換わります。
本体はBashスクリプト(sdkman-cli)とRust製のネイティブ部品(sdkman-cli-native)の2層です。ネイティブ版0.7.34のソースに実装があるのは current・default・help・home・uninstall・version の6コマンドで、インストールや env はまだBash側が処理します。設定の sdkman_native_enable=true(既定)がこの切り替えを担います。
候補はJVMのエコシステムに限られます。公式のVendorsページは、Go・Rust・Node.js・Python・Rubyのツールチェーンを「SDKMAN!の居場所ではない」と書いています。JDKは各社が自分で登録するのではなく、Foojay DISCO APIから自動で取り込まれます。
| 識別子の接尾辞 | ディストリビューション | 識別子の例(macOS x64で取得) |
|---|---|---|
| tem | Eclipse Temurin | 26.0.2-tem |
| amzn | Amazon Corretto | 27.0.0.0-amzn |
| zulu | Azul Zulu | 27.0.0+35-zulu |
| librca | BellSoft Liberica | 27.0.0+36-librca |
| graalce | GraalVM Community | 25.0.1-graalce |
| graal | Oracle GraalVM | 25.0.1-graal |
| ms | Microsoft Build of OpenJDK | 25.0.4.0-ms |
| oracle | Oracle JDK | 27.0.0-oracle |
| open | jdk.java.net(OpenJDKビルド) | 27.ea.22-open |
GraalVMは graalce(コミュニティ版)と graal(Oracle GraalVM)で配布元とライセンスが違うため、識別子を取り違えないようにします。Native Imageの使い方はGraalVMとは?JVMとの違いとNative Imageの作り方【2026年版】、ディストリビューションごとの商用利用の条件はOpenJDKは商用利用できる?:無料の範囲とOracle JDKとの違い・ライセンス・サポート期限【2026年最新】で整理しています。
SDKMAN!のインストール手順(Linux・macOS・Windows)
Linuxでの導入と依存コマンド
インストーラーは起動直後に unzip・zip・tar・find・curl・sed の有無を順に調べ、1つでも無ければその場で終了します。Debian・Ubuntuの最小構成では zip と unzip が入っていないことが多いので、先に入れておきます。
sudo apt-get install -y zip unzip curl
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk version
Linuxでは、インストーラーはBashがあれば ~/.bashrc、zshがあれば ~/.zshrc の末尾に初期化スニペットを追記します。このスニペットには、設定ファイルの末尾に置くよう注記があり、後から別のPATH設定をその下に書くとSDKMAN!のPATHが上書きされます。各ファイルの読み込み順は.bashrcとは?.bash_profileとの読み込み順の違いと書き方・反映手順が詳しいです。
macOSでBash 3.2のエラーを避ける方法
sdkman-hooksリポジトリの2026年3月16日のコミット(c21bdf4)で、インストーラーはBash 4未満を検知すると即座に終了するようになりました。macOSに標準で入っている /bin/bash は3.2.57なので、公式サイトの curl -s "https://get.sdkman.io" | bash をそのまま流すと次のように止まります。
Checking Bash version...
======================================================================================================
SDKMAN requires Bash 4 or higher, but you are running Bash 3.2.57(1)-release.
Please upgrade Bash using your system's package manager.
On macOS, you can install a modern Bash with Homebrew:
$ brew install bash
この検査は $BASH_VERSION があるときだけ動くため、公式ドキュメントの「zsh」タブにある curl -s "https://get.sdkman.io" | zsh なら通ります。実測では、この方法で5.23.2とネイティブ版0.7.34(darwinx64)が入りました。入れた後は、macOS標準のBash 3.2から sdkman-init.sh を読み込んでも sdk use や sdk env が動きました(5.23.2はBash 3.2で失敗していた大文字変換の修正を含みます)。Bashで使い続けるなら brew install bash で5系を入れ、PATHの先頭に置いてから実行する方法でも構いません。
macOSでは、Bash用のスニペットは ~/.bashrc ではなく ~/.bash_profile に書かれます。ターミナルの既定シェルがzshなら ~/.zshrc 側が効きます。
Windowsでの導入経路:WSL2とGit Bash
SDKMAN!はBash環境が前提で、PowerShellやコマンドプロンプトには入りません。公式のインストール手順が挙げる経路は2つです。
- WSL2:Ubuntuなどのディストリビューション内で、Linuxと同じ手順で入れる。Cygwinで実行するとインストーラーは「SDKMAN does not support Cygwin」と表示し、WSL2を使うよう案内して終了する
- Git Bash:インストーラーは
MINGW・MSYSをwindowsx64として扱う。ただしGit Bashにはzipとunzipが無いため、MSYS2から補う必要がある(公式も「いくつか問題はあるが概ね動く」という表現にとどめている)
WSL2に入れたJDKはLinux向けのビルドで、Windows側のPATHや JAVA_HOME には入りません。WSL自体の準備はWSLで開発環境を構築する手順|.wslconfig調整とDocker連携・肥大化の対処を参照してください。
SDKMAN!自体のアンインストール
アンインストール用のコマンドはありません。公式の手順は、~/.sdkman を削除し、シェル設定ファイルから初期化スニペットを手で消す、の2段階です。入れたJDKも ~/.sdkman/candidates の下にあるため一緒に消えます。
tar zcvf "$HOME/sdkman-backup_$(date +%F-%Hh%M).tar.gz" -C "$HOME" .sdkman &&
rm -rf ~/.sdkman
# .bashrc・.bash_profile・.profile・.zshrc から sdkman-init.sh を読む行を削除する
個別のバージョンを消すだけなら sdk uninstall java <識別子> です。既定版を消そうとすると「java 25.0.4-tem is the current version and should not be removed.」と表示されて止まり、--force を付けて消すとその候補が使えなくなります。
Javaのインストールと切り替え(install・use・default)
sdk list java はベンダーごとにバージョンと識別子(Identifier)を並べ、Use列に >(使用中)・*(インストール済み)・+(ローカル登録のみ)を表示します。識別子は「バージョン-接尾辞」の形なので、この一覧からコピーして使います。
sdk list java
sdk install java # 既定版(2026-10-08時点は 25.0.4-tem)
sdk install java 21.0.12+1.1-zulu # 識別子を指定
sdk use java 21.0.12+1.1-zulu # このシェルだけ切り替え
sdk default java 25.0.4-tem # 新しく開くシェルの既定を変更
sdk home java 25.0.4-tem # インストール先の絶対パスを表示
手元のmacOS(Intel)では、sdk install java のダウンロードから展開までが約32秒でした(回線速度に依存します)。展開後の 25.0.4-tem は246MBあります。インストール時には「既定にするか」を確認され、sdkman_auto_answer=true のときは確認なしで既定に設定されます。
sdk currentが既定版を表示する落とし穴
公式ドキュメントでは、sdk current java は「Using java version 21.0.4-tem」のようにいま使っている版を返すと説明されています。しかしネイティブ版0.7.34の環境で sdk use java my-local の直後に実行すると、「Current default java version 25.0.4-tem」と既定版が返りました。sdkman_native_enable=false に切り替えて同じ操作をすると、Bash実装が「Using java version my-local」を返します。シェルで実際に効いている版は、echo $JAVA_HOME か java -version で確かめてください。
JAVA_HOMEとIDEの設定
既定版だけを使う場合、JAVA_HOME は ~/.sdkman/candidates/java/current です。IntelliJ IDEAなどのIDEにJDKを登録するときもこのパスを指定すると、sdk default で既定版を変えたときにIDE側も追従します。特定の版に固定したいなら、sdk home java <識別子> で出たパスを登録します。IDE側の操作はIntelliJ IDEAでJava開発を始める手順|インストール・JDK設定・日本語化にまとめています。
既存JDK・SNAPSHOTのローカル登録
他の方法で入れたJDKや自前ビルドは、パスを3つ目の引数に渡すとSDKMAN!の管理下に置けます。実体は移動せず、candidates/java/my-local というシンボリックリンクが作られるだけです。
sdk install java my-local "$HOME/.local/java/jdk-25.0.4.1+1/Contents/Home"
# Linking java my-local to .../jdk-25.0.4.1+1/Contents/Home
# Done installing!
sdk list java では「Unclassified」の行に + 付きで表示されます。名前は配布されている識別子と重複できません。sdk uninstall で消えるのはリンクだけで、元のJDKはそのまま残ります。
.sdkmanrcによるプロジェクト単位のバージョン固定
プロジェクトのルートで sdk env init を実行すると、そのシェルで使用中の版を書いた .sdkmanrc が作られます。複数の候補を キー=値 で並べられます。
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=25.0.4-tem
maven=3.9.11
実測では、sdk use java my-local の後に sdk env init を実行すると java=my-local が書き込まれました。ローカル登録の名前はほかのメンバーの環境に存在しないので、Gitに含める前に sdk list java にある識別子へ書き換えます。
| コマンド | 動作(5.23.2で実測) |
|---|---|
| sdk env | .sdkmanrcの版をこのシェルに適用 |
| sdk env install | 未導入の版をダウンロードして適用 |
| sdk env clear | 既定版へ戻す |
| sdkman_auto_env=true | cdで入ると適用・出ると既定版へ戻す |
sdk env install は、その候補をまだ1つも入れていなければ、入れた版を既定にも設定します(実測ではmaven 3.9.11が既定になりました)。既に既定版がある候補では、5.22.5の修正で既定を上書きしなくなっています。
注意したいのは、sdkman-init.sh を読まない非対話シェルです。CIのスクリプトやAIコーディングエージェントが実行する1行ずつのBashでは .sdkmanrc は自動適用されません。使用されるJDKは継承したPATH・JAVA_HOMEやビルド設定によるため、同じプロセスの中で読み込みと適用をまとめて実行します。
bash -c 'source "$HOME/.sdkman/bin/sdkman-init.sh" && sdk env && ./gradlew build'
設定ファイル~/.sdkman/etc/configの主要キー
設定は ~/.sdkman/etc/config に1行1キーで書かれ、sdk config でエディタが開きます。インストーラーが書き込む値は次のとおりです。
| キー | 既定値 | ci=true時 | 用途 |
|---|---|---|---|
| sdkman_auto_answer | false | true | 確認プロンプトに自動でYes |
| sdkman_selfupdate_feature | true | false | 本体更新の自動確認 |
| sdkman_colour_enable | true | false | 色付き出力 |
| sdkman_auto_env | false | false | cdで.sdkmanrcを自動適用 |
| sdkman_checksum_enable | true | true | アーカイブのチェックサム検証 |
| sdkman_healthcheck_enable | true | true | 起動時のAPI到達確認 |
| sdkman_native_enable | true | true | Rust製コマンドを使う |
| sdkman_curl_connect_timeout | 7 | 7 | 接続タイムアウト(秒) |
公式ドキュメントの設定例は sdkman_curl_connect_timeout=5 と書いていますが、2026年10月時点のインストーラーが書き込むのは7です。旧版にあった sdk offline は5.23.2では「Invalid command: offline」となり、廃止されています。回線が遅い環境で起動が待たされる場合は、sdkman_healthcheck_enable=false で起動時の到達確認を止めます。
update・upgrade・selfupdateの違いと脆弱性対応
名前が似た更新系コマンドは、対象がそれぞれ違います。
sdk selfupdate:SDKMAN!本体を更新する。forceを付けると再インストールsdk update:候補一覧のメタデータを更新する(新しい候補が使えるようになる)sdk upgrade [候補]:入れているSDKより新しい既定版があれば、入れ替えを提案するsdk flush:tmpのダウンロード済みアーカイブなどを消す。実測では10個・147MBが解放された
sdk upgrade は差分を表示するだけのコマンドではありません。sdkman_auto_answer=true の環境で sdk upgrade maven を実行すると、確認なしで3.10.0をダウンロードし、既定を3.9.11から3.10.0へ切り替えました(旧版は残ります)。CI用の設定のまま手元で実行すると、気付かないうちに既定版が変わります。
2026年5月4日に公開されたセキュリティアドバイザリGHSA-jh7h-4x3r-f89r(深刻度Critical)では、チェックサム検証で eval にバージョン文字列を渡しており、細工された識別子をAPIが返すと sdk install の途中で任意のコマンドが実行される問題が報告されました。影響を受けるのは5.22.5で、5.23.0で eval を取り除いて修正されています。sdk version のscriptが5.23.0未満なら sdk selfupdate を実行してください。
CI/CDとDockerでの使い方
CIでSDKMAN!そのものを入れる場合は、インストーラーのパラメーターで非対話用に切り替えます。ci=true は上の表のとおり自動応答・色なし・自己更新なしを設定し、rcupdate=false はシェル設定ファイルに手を付けません。
curl -s "https://get.sdkman.io?ci=true&rcupdate=false" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk env install
ただしGitHub Actionsでは、SDKMAN!を入れるより actions/setup-java@v6 に .sdkmanrc を読ませる方が手数が少なくなります。公式の sdkman/sdkman-action はアーカイブ済み(最終更新2024年3月)です。setup-javaは java-version-file に .sdkmanrc を指定すると java= の行を読み、接尾辞からディストリビューションも推定します。
- uses: actions/checkout@v7
- uses: actions/setup-java@v6
with:
java-version-file: .sdkmanrc
- run: ./gradlew build
推定できる接尾辞は tem→temurin、amzn→corretto、zulu→zulu、librca→liberica、ms→microsoft、graal・graalce→graalvm など12系統です。表に無い open や nik を書いた場合は distribution の明示が必要です。読むのはjavaの行だけなので、MavenやGradleの版はラッパー(mvnw・gradlew)で固定します。ビルドツール側でJDKを指定する方法はツールチェーン(toolchain)とは?構成要素と言語別の実例・GradleのJava Toolchain設定で比べています。
Dockerイメージでは、JDK入りのベースイメージを選べばSDKMAN!本体やzip・unzipを入れずに済みます。SDKMAN!を使うなら、インストールと sdk flush を同じ RUN にまとめます。公式ドキュメントは .sdkman/tmp などを手で消すと壊れると明記しており、rm -rf で片付けるのは避けます。
jEnv・asdf・miseとの選び分け
| ツール | JDKの取得 | 対象 | 設定ファイル | 最新版 |
|---|---|---|---|---|
| SDKMAN! | する | JVM系SDK | .sdkmanrc | 5.23.2 |
| jEnv | しない | Javaのみ | .java-version | 0.6.0 |
| asdf | プラグイン経由 | 多言語 | .tool-versions | v0.20.2 |
| mise | する | 多言語 | mise.toml | v2026.10.4 |
JVMの仕事だけでGradle・Maven・Kotlin・Scala・Spring Boot CLIまで同じ手順でそろえたいなら、候補の幅でSDKMAN!が有利です。jEnvはJDKをダウンロードせず、別途入れたJDKを jenv add で登録して切り替えるだけなので、SDKMAN!で入れたJDKをjEnvで切り替えるような二重管理は避けます。
フロントエンドのNode.jsやPythonも同じリポジトリで扱うなら、miseに寄せる方が設定ファイルが1つで済みます。miseは mise settings add idiomatic_version_file_enable_tools java を設定すると .sdkmanrc のjava行も読み、20.0.2-tem を temurin-20.0.2 に読み替えます。ただしmise公式は graal・nik・bsg の3系統を対応外としており、Zuluは細かい版でなくメジャー版(zulu-11)に丸められます。移行前に .sdkmanrc の識別子を確認してください。miseの導入手順はmiseとは?mise.tomlでツール・環境変数・タスクを束ねる導入手順【2026年版】にあります。
SDKMAN!を選ばない方がよいのは、Windowsネイティブ(PowerShell)だけで開発するチームと、fishシェルを使う人です。公式の対応シェルはBashとzshだけで、fish向けの第三者プラグインsdkman-for-fishの最新リリースは2024年4月のv2.1.0で止まっています。シェル起動時の負荷は、手元のIntel Macで sdkman-init.sh の読み込みがzshで約67ms、Bash 5で約23msの上乗せでした(各15回の中央値)。
SDKMAN!でよくあるエラーと対処
- 新しいターミナルで sdk: command not found:初期化スニペットが読まれていない。macOSのBashは
~/.bash_profile、zshは~/.zshrcを確認し、スニペットが末尾にあるかを見る - Stop! java 99.0.0-foo is not available:識別子の誤りか、そのOS・CPU向けのビルドが無い。
sdk list javaの識別子をそのまま使う - Stop! Candidate version is not installed.:
sdk useは未導入の版に切り替えない。先にsdk installを実行する - ダウンロードが途中で止まる:取得にはcurlを使うため、社内プロキシ下では
https_proxy環境変数の設定を確認する。遅い回線ではsdkman_curl_max_timeを延ばす - IDEとターミナルでJDKが違う:IDEに特定版のパスを登録している。
~/.sdkman/candidates/java/currentを登録するか、プロジェクトのJDK設定を合わせる
よくある質問
SDKMAN!とは何ですか?
JavaのJDKやGradle・Maven・Kotlinなど、JVM系のSDKを複数バージョン入れて切り替えるコマンドラインツールです。Apache License 2.0で公開されており、2026年10月時点の最新はスクリプト版5.23.2です。
WindowsでSDKMAN!は使えますか?
WSL2の中か、zip・unzipを追加したGit Bashで使えます。PowerShellやコマンドプロンプトには入らず、Cygwinではインストーラーが終了します。
SDKMAN!でNode.jsやPythonは管理できますか?
できません。公式はJVM以外のツールチェーンを候補に入れない方針で、Node.jsやPythonもまとめて管理するならmiseやasdfを使います。
sdk useとsdk defaultの違いは何ですか?
sdk use は実行したシェルだけを切り替え、閉じると元に戻ります。sdk default は current のリンク先を変えるため、以後に開くシェルすべてに効きます。
SDKMAN!をアンインストールするには?
rm -rf ~/.sdkman で本体と入れたSDKを消し、.bashrc・.bash_profile・.zshrc から sdkman-init.sh を読む行を削除します。専用のアンインストールコマンドはありません。