CLOVER🍀

That was when it all began.

SDKMANでプロジェクトで使うJDK/SDKを管理する

これは、なにをしたくて書いたもの?

プロジェクトで使うJDK/SDKをSDKMANの設定ファイルで管理できるというのは知っていたのですが、自分で試したことが
なかったので確認しておこうかなと。

.sdkmanrc

端的に言うと、.sdkmanrcというファイルで管理します。

Usage / Env Command

このファイルを作成しておくことで、プロジェクトで使うJDK/SDKの切り替えが簡単になります。

使うコマンドはこちらですね。

  • sdk env init … .sdkmanrcファイルの作成
  • sdk env … .sdkmanrcファイルの内容に環境を切り替える
  • sdk env clear … .sdkmanrcファイルから読み込んだ内容をクリアする
  • sdk env install … .sdkmanrcファイルに書かれているJDK/SDKをインストールする

ディレクトリーを変更した時に自動的にsdk envコマンド相当のことを行いたい場合は、sdkman_auto_env=true
$HOME/.sdkman/etc/configファイルに設定します。

Usage / Configuration

注意点としては、ディレクトリーを移動するとプロジェクト固有のJDK/SDKを設定した状態がリセットされるようです。

このあたりは実際に確認して試してみましょうという感じですね。

環境

今回の環境はこちら。

$ sdk version

SDKMAN!
script: 5.20.0
native: 0.7.16 (linux x86_64)

この時点ではいずれのJDK/SDKもインストールしていないものとします。

.sdkmanrcファイルでプロジェクトごとに使用するJDK/SDKを切り替える

なにもないところからスタートするのもなんなので、Eclipse Temurinの25をインストールしてデフォルトバージョンに
指定しておきます。

$ sdk install java 25.0.2-tem

...

Setting java 25.0.2-tem as default.

プロジェクトを作成。

$ mkdir project1 project2

project1へ移動。

$ cd project1

この時点ではsdk envコマンドを実行してもエラーになります。

$ sdk env
Could not find .sdkmanrc in the current directory.

Run 'sdk env init' to create it.

.sdkmanrcファイルを作成します。

$ sdk env init
.sdkmanrc created.

こんな内容になりました。

.sdkmanrc

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

これをこのように変更。

.sdkmanrc

# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=21.0.10-tem
maven=3.9.12

sdk envコマンドを実行しても、まだ動きません。必要なJDK/SDKをインストールする必要があります。

$ sdk env
Stop! java 21.0.10-tem is not installed.

Run 'sdk env install' to install it.

インストール。

$ sdk env install
Downloading: java 21.0.10-tem

In progress...

######################################################################## 100.0%

Repackaging Java 21.0.10-tem...

Done repackaging...

Installing: java 21.0.10-tem
Done installing!


Downloading: maven 3.9.12

In progress...

######################################################################## 100.0%

Installing: maven 3.9.12
Done installing!


Using java version 21.0.10-tem in this shell.
Setting maven version 3.9.12 as default.

Using maven version 3.9.12 in this shell.

Javaは切り替わりましたが、Apache Mavenは使えません…。どうやら対象のSDKが初めてインストールされた場合は、
シェルを再起動する必要がありそうです…。

$ java --version
openjdk 21.0.10 2026-01-20 LTS
OpenJDK Runtime Environment Temurin-21.0.10+7 (build 21.0.10+7-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.10+7 (build 21.0.10+7-LTS, mixed mode, sharing)


$ mvn --version
コマンド 'mvn' が見つかりません。次の方法でインストールできます:
apt install maven
管理者に確認してください。

シェルを再起動して確認。

$ java --version
openjdk 21.0.10 2026-01-20 LTS
OpenJDK Runtime Environment Temurin-21.0.10+7 (build 21.0.10+7-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.10+7 (build 21.0.10+7-LTS, mixed mode, sharing)


$ mvn --version
Apache Maven 3.9.12 (848fbb4bf2d427b72bdb2471c22fced7ebd9a7a1)
Maven home: $HOME/.sdkman/candidates/maven/3.9.12
Java version: 21.0.10, vendor: Eclipse Adoptium, runtime: $HOME/.sdkman/candidates/java/21.0.10-tem
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "6.8.0-100-generic", arch: "amd64", family: "unix"

OKですね。

project2へ移動して、.sdkmanrcファイルを作成。

$ cd project2
$ sdk env init

内容はこうしました。

.sdkmanrc

# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=17.0.18-tem
gradle=9.3.1

JDK/SDKのインストール。

$ sdk env install

今回、Gradleは初めてインストールしたのでシェルを再起動してからsdk envコマンドを実行。

$ sdk env

Using java version 17.0.18-tem in this shell.

Using gradle version 9.3.1 in this shell.

バージョン確認。

$ java --version
openjdk 17.0.18 2026-01-20
OpenJDK Runtime Environment Temurin-17.0.18+8 (build 17.0.18+8)
OpenJDK 64-Bit Server VM Temurin-17.0.18+8 (build 17.0.18+8, mixed mode, sharing)


$ gradle --version

Welcome to Gradle 9.3.1!

Here are the highlights of this release:
 - Test reporting improvements
 - Error and warning improvements
 - Build authoring improvements

For more details see https://docs.gradle.org/9.3.1/release-notes.html


------------------------------------------------------------
Gradle 9.3.1
------------------------------------------------------------

Build time:    2026-01-29 14:15:01 UTC
Revision:      44f4e8d3122ee6e7cbf5a248d7e20b4ca666bda3

Kotlin:        2.2.21
Groovy:        4.0.29
Ant:           Apache Ant(TM) version 1.10.15 compiled on August 25 2024
Launcher JVM:  17.0.18 (Eclipse Adoptium 17.0.18+8)
Daemon JVM:    $HOME/.sdkman/candidates/java/17.0.18-tem (no Daemon JVM specified, using current Java home)
OS:            Linux 6.8.0-100-generic amd64

OKですね。

プロジェクトのJDK/SDKの設定をクリアするにはsdk env clearコマンドを実行します。

$ sdk env clear
Restored java version to 25.0.2-tem (default)
Restored maven version to 3.9.12 (default)

sdkman_auto_env=trueを設定する

現在の設定だと、.sdkmanrcファイルがあるディレクトリーに移動してもsdk envコマンドを明示的に実行しない限りは
JDK/SDKが切り替わりません。

また他のディレクトリーに移動しても設定したJDK/SDKはそのままです。

つまり、.sdkmanrcファイルは指定のJDK/SDKを使うようにカレントシェルを設定する機能だと考えられます。

これを.sdkmanrcファイルが存在するディレクトリーに移動すると、自動的にsdk envコマンドを実行したことにするには
SDKMANの設定ファイルにsdkman_auto_env=trueを設定します。

$HOME/.sdkman/etc/configファイルを見ると、以下のように書かれているので

sdkman_auto_env=false

こう変更します。

sdkman_auto_env=true

この設定はsdk configコマンドで変更できます。

$ sdk config

この状態でシェルを再起動すると設定が反映されます。

project1に移動。

$ cd project1

Using java version 21.0.10-tem in this shell.

Using maven version 3.9.12 in this shell.

JavaとApache Mavenのバージョンが切り替わりました。確認は省略します。

project2に移動。

$ cd ../project2
Restored java version to 25.0.2-tem (default)
Restored maven version to 3.9.12 (default)

Using java version 17.0.18-tem in this shell.

Using gradle version 9.3.1 in this shell.

JavaとGradleになりましたね。

これで.sdkmanrcファイルが存在しないディレクトリーに移動すると、SDKMANのデフォルトに指定されているJDK/SDKに
リセットされるようです。

$ cd ..
Restored java version to 25.0.2-tem (default)
Restored maven version to 3.9.12 (default)

どうも、移動したディレクトリーに.sdkmanrcファイルがあればその内容に設定し、.sdkmanrcファイルがなければ
設定がクリアされるような挙動に見えたのですが、そうみたいですね。

https://github.com/sdkman/sdkman-cli/blob/5.20.0/src/main/bash/sdkman-init.sh#L164-L169

おわりに

SDKMANでプロジェクトで使うJDK/SDKを管理する機能を試してみました。

だいぶ今さらながらに試してみたのですが、このブログでは複数のバージョンをプロジェクトごとに使い分けることは
少ないというか、だいたい最新版で進めてしまうのであまり使うことはないと思います…。

とはいえ、1度使って感覚を押さえておこうかなというのが今回使ってみた意図ではあるのですが。

複数バージョンを使い分けなければならない状態になったら、他のツールを使った方がよさそうだなと思いはしました。