これは、なにをしたくて書いたもの?
自分はJavaに関するソフトウェアをインストールするのに、よくSDKMANを使っています。
Home | SDKMAN! the Software Development Kit Manager
環境によってはmiseを使っていることもあるのですが、Javaに関するものに特化する場合はSDKMANの方が
便利だなと思ったりします。
そんな感じでずっと使っているのですが、SDKMANの一部がいつの間にかRustになっていることに気づいたので
ちょっとメモしておこうかなということで。
環境
今回の環境はこちら。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 24.04.2 LTS Release: 24.04 Codename: noble $ uname -srvmpio Linux 6.8.0-62-generic #65-Ubuntu SMP PREEMPT_DYNAMIC Mon May 19 17:15:03 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
SDKMANをインストールする
まずはSDKMANをインストールします。
$ curl -s "https://get.sdkman.io" | bash $ source "/home/vagrant/.sdkman/bin/sdkman-init.sh"
Installation | SDKMAN! the Software Development Kit Manager
これでSDKMANが使えるようになります。
バージョンを確認。
$ sdk version SDKMAN! script: 5.19.0 native: 0.7.4 (linux x86_64)
ここで「native」と出てくるのがヒントですね。
なにがnative?
$ declare -f sdk sdk () { COMMAND="$1"; QUALIFIER="$2"; case "$COMMAND" in l) COMMAND="list" ;; ls) COMMAND="list" ;; v) COMMAND="version" ;; u) COMMAND="use" ;; i) COMMAND="install" ;; rm) COMMAND="uninstall" ;; c) COMMAND="current" ;; ug) COMMAND="upgrade" ;; d) COMMAND="default" ;; h) COMMAND="home" ;; e) COMMAND="env" ;; esac; if [[ "$COMMAND" != "update" ]]; then ___sdkman_check_candidates_cache "$SDKMAN_CANDIDATES_CACHE" || return 1; fi; SDKMAN_AVAILABLE="true"; if [ -z "$SDKMAN_OFFLINE_MODE" ]; then SDKMAN_OFFLINE_MODE="false"; fi; __sdkman_update_service_availability; if [ -f "${SDKMAN_DIR}/etc/config" ]; then source "${SDKMAN_DIR}/etc/config"; fi; if [[ -z "$COMMAND" ]]; then ___sdkman_help; return 1; fi; CMD_FOUND=""; if [[ "$COMMAND" != "selfupdate" || "$sdkman_selfupdate_feature" == "true" ]]; then CMD_TARGET="${SDKMAN_DIR}/src/sdkman-${COMMAND}.sh"; if [[ -f "$CMD_TARGET" ]]; then CMD_FOUND="$CMD_TARGET"; fi; fi; CMD_TARGET="${SDKMAN_DIR}/ext/sdkman-${COMMAND}.sh"; if [[ -f "$CMD_TARGET" ]]; then CMD_FOUND="$CMD_TARGET"; fi; if [[ -z "$CMD_FOUND" ]]; then echo ""; __sdkman_echo_red "Invalid command: $COMMAND"; echo ""; ___sdkman_help; fi; if [[ "$COMMAND" == "offline" && -n "$QUALIFIER" && -z $(echo "enable disable" | grep -w "$QUALIFIER") ]]; then echo ""; __sdkman_echo_red "Stop! $QUALIFIER is not a valid offline mode."; fi; local final_rc=0; local native_command="${SDKMAN_DIR}/libexec/${COMMAND}"; if [[ "$sdkman_native_enable" == 'true' && -f "$native_command" ]]; then "$native_command" "${@:2}"; else if [ -n "$CMD_FOUND" ]; then if [[ -n "$QUALIFIER" && "$COMMAND" != "help" && "$COMMAND" != "offline" && "$COMMAND" != "flush" && "$COMMAND" != "selfupdate" && "$COMMAND" != "env" && "$COMMAND" != "completion" && "$COMMAND" != "edit" && "$COMMAND" != "home" && -z $(echo ${SDKMAN_CANDIDATES[@]} | grep -w "$QUALIFIER") ]]; then echo ""; __sdkman_echo_red "Stop! $QUALIFIER is not a valid candidate."; return 1; fi; local converted_command_name=$(echo "$COMMAND" | tr '-' '_'); __sdk_"$converted_command_name" "${@:2}"; fi; fi; final_rc=$?; return $final_rc }
nativeといっているのはこのあたりみたいですね。
local native_command="${SDKMAN_DIR}/libexec/${COMMAND}"; if [[ "$sdkman_native_enable" == 'true' && -f "$native_command" ]]; then "$native_command" "${@:2}";
SDKMAN_DIR
というのは$HOME/.sdkman
ディレクトリーのことです。
$ printenv SDKMAN_DIR $HOME/.sdkman
ということは、nativeなコマンドはここにあるわけですね。
$ ll ${SDKMAN_DIR}/libexec 合計 6148 drwxrwxr-x 2 xxxxx xxxxx 4096 6月 28 15:20 ./ drwxrwxr-x 11 xxxxx xxxxx 4096 6月 28 15:20 ../ -rwxr-xr-x 1 xxxxx xxxxx 1120624 6月 28 15:20 current* -rwxr-xr-x 1 xxxxx xxxxx 1179520 6月 28 15:20 default* -rwxr-xr-x 1 xxxxx xxxxx 1202120 6月 28 15:20 help* -rwxr-xr-x 1 xxxxx xxxxx 1119760 6月 28 15:20 home* -rwxr-xr-x 1 xxxxx xxxxx 1148920 6月 28 15:20 uninstall* -rwxr-xr-x 1 xxxxx xxxxx 505608 6月 28 15:20 version*
この6つがnativeなようです。
versionコマンドを実行してみましょう。
$ ${SDKMAN_DIR}/libexec/version SDKMAN! script: 5.19.0 native: 0.7.4 (linux x86_64)
すべてがnativeコマンドであるわけではなく、その他のコマンドはこちらにあるようです。
CMD_FOUND=""; if [[ "$COMMAND" != "selfupdate" || "$sdkman_selfupdate_feature" == "true" ]]; then CMD_TARGET="${SDKMAN_DIR}/src/sdkman-${COMMAND}.sh"; if [[ -f "$CMD_TARGET" ]]; then CMD_FOUND="$CMD_TARGET"; fi; fi;
確認。
$ ll ${SDKMAN_DIR}/src 合計 104 drwxr-xr-x 2 xxxxx xxxxx 4096 6月 28 15:20 ./ drwxrwxr-x 11 xxxxx xxxxx 4096 6月 28 15:20 ../ -rw-r--r-- 1 xxxxx xxxxx 2485 6月 28 15:20 sdkman-availability.sh -rw-r--r-- 1 xxxxx xxxxx 1024 6月 28 15:20 sdkman-cache.sh -rw-r--r-- 1 xxxxx xxxxx 941 6月 28 15:20 sdkman-config.sh -rw-r--r-- 1 xxxxx xxxxx 2139 6月 28 15:20 sdkman-current.sh -rw-r--r-- 1 xxxxx xxxxx 1326 6月 28 15:20 sdkman-default.sh -rw-r--r-- 1 xxxxx xxxxx 3169 6月 28 15:20 sdkman-env-helpers.sh -rw-r--r-- 1 xxxxx xxxxx 4297 6月 28 15:20 sdkman-env.sh -rw-r--r-- 1 xxxxx xxxxx 1575 6月 28 15:20 sdkman-flush.sh -rw-r--r-- 1 xxxxx xxxxx 2688 6月 28 15:20 sdkman-help.sh -rw-r--r-- 1 xxxxx xxxxx 1299 6月 28 15:20 sdkman-home.sh -rw-r--r-- 1 xxxxx xxxxx 7646 6月 28 15:20 sdkman-install.sh -rw-r--r-- 1 xxxxx xxxxx 3228 6月 28 15:20 sdkman-list.sh -rw-r--r-- 1 xxxxx xxxxx 3518 6月 28 15:20 sdkman-main.sh -rw-r--r-- 1 xxxxx xxxxx 920 6月 28 15:20 sdkman-offline.sh -rw-r--r-- 1 xxxxx xxxxx 2473 6月 28 15:20 sdkman-path-helpers.sh -rw-r--r-- 1 xxxxx xxxxx 2349 6月 28 15:20 sdkman-selfupdate.sh -rw-r--r-- 1 xxxxx xxxxx 1503 6月 28 15:20 sdkman-uninstall.sh -rw-r--r-- 1 xxxxx xxxxx 2357 6月 28 15:20 sdkman-update.sh -rw-r--r-- 1 xxxxx xxxxx 3443 6月 28 15:20 sdkman-upgrade.sh -rw-r--r-- 1 xxxxx xxxxx 1956 6月 28 15:20 sdkman-use.sh -rw-r--r-- 1 xxxxx xxxxx 3040 6月 28 15:20 sdkman-utils.sh -rw-r--r-- 1 xxxxx xxxxx 791 6月 28 15:20 sdkman-version.sh
ちなみに、こちら見ると${SDKMAN_DIR}/ext
ディレクトリーにスクリプトを置くと自分でコマンドを追加できそうですね。
CMD_TARGET="${SDKMAN_DIR}/ext/sdkman-${COMMAND}.sh"; if [[ -f "$CMD_TARGET" ]]; then CMD_FOUND="$CMD_TARGET"; fi;
このスクリプトの本体はこちらです。
https://github.com/sdkman/sdkman-cli/blob/5.19.0/src/main/bash/sdkman-main.sh
少し脱線しました。
いつからnativeコマンドが入った?
SDKMANはbashスクリプトのイメージだったので、いつからこうなったのか調べてみました。
どうやらSDKMAN 5.13.0のようです。
Add capability for native binary support
https://github.com/sdkman/sdkman-cli/releases/tag/5.13.0
5.13.0のリリース日を見ると、2021年10月18日です。かなり前からですね?そんなに気づかなかったのでしょうか?
nativeの実体は?
nativeの実体は、こちらのリポジトリーです。sdkman-cli-nativeですね。
Native CLI subcommand components for SDKMAN! written in Rust. Use the binaries generated by this project in the sdk wrapper shell function from the sdkman-cli project.
GitHub - sdkman/sdkman-cli-native: The next generation of SDKMAN! CLI commands, written in Rust
Rustで実装されているようです。
こちらで表示されていた「native」というのは、sdkman-cli-nativeのバージョンのことだったわけですね。
$ sdk version SDKMAN! script: 5.19.0 native: 0.7.4 (linux x86_64)
Release Release v0.7.4 · sdkman/sdkman-cli-native · GitHub
ところで、0.0.1のリリース日を見ると2022年2月10日になっています。最初はちょっと違ったんでしょうね…?
Release Release v0.0.1 · sdkman/sdkman-cli-native · GitHub
ちょっと気になりましたが、あまり追わないことにします。
おわりに
SDKMANのバージョン表記に「native」と出てくるのがちょっと気になって、少し調べてみました。
2021年からネイティブに切り替わっていっていたことに全然気づいてなかったのですが、すでに4年経過しています。
よくここまで気づいていなかったとも思ったのですが、そもそもこのツールは最初はSDKMANではなくGVMという名前でした。
それは10年以上前の話です。
使い勝手がまったく変わらないので、ツールの名前が変わっても自然に使っていたのですが、意外と気づかないもの
なんだなぁと。
そして、こういうところでもRustが使われているですね。