はじめに
Mac 上に複数の JDK が共存している環境で、jdk <バージョン> の 1 コマンドだけで
Java を切り替える仕組みを作りました。
Liberty の起動の際などに使用しています。
動作確認環境は macOS + zsh + oh-my-zsh です。
本スクリプトは /usr/libexec/java_home を使用しているため、macOS 専用です。
Linux / Windows では動作しません。
背景:複数 Java が共存する環境
/usr/libexec/java_home -V を実行すると、次のように複数の JVM が検出されます。
# /usr/libexec/java_home -V の出力例(環境によって異なります)
Matching Java Virtual Machines (8):
21.0.x (arm64) "Oracle Corporation" - "Java SE 21"
21.0.x (arm64) "IBM Corporation" - "IBM Semeru 21 JRE"
17.0.x (arm64) "IBM Corporation" - "IBM Semeru 17 JRE"
11.0.x (arm64) "IBM Corporation" - "IBM Semeru 11 JRE"
8.0.x (x86_64)"IBM Corporation" - "IBM Semeru 8"
...
プロジェクトによって使用する JDK が異なるため、毎回 export JAVA_HOME=...
を手で打つのは手間です。これを 1 コマンドにまとめるのが本スクリプトです。
作成したファイル
~/switch-java.sh
Java バージョンを切り替えるメインスクリプトです。
#!/bin/bash
# Color codes for better readability
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to display available Java versions
show_java_versions() {
echo -e "${BLUE}Available Java versions:${NC}"
/usr/libexec/java_home -V 2>&1 | grep -E "^\s+[0-9]" | nl -w2 -s'. '
}
# Function to set Java version
set_java_version() {
local version=$1
local java_home_path=$(/usr/libexec/java_home -v "$version" 2>/dev/null)
if [ $? -eq 0 ] && [ -n "$java_home_path" ]; then
export JAVA_HOME="$java_home_path"
export PATH="$JAVA_HOME/bin:$PATH"
echo -e "${GREEN}✓ Java version switched successfully!${NC}"
echo -e "${YELLOW}JAVA_HOME:${NC} $JAVA_HOME"
echo ""
java -version
return 0
else
echo -e "${RED}✗ Error: Java version '$version' not found${NC}"
return 1
fi
}
# Main logic
if [ -z "$1" ]; then
show_java_versions
echo ""
echo -e "${YELLOW}Enter version number (e.g., 21, 17, 11, 8):${NC}"
read -p "> " selected_version
if [ -n "$selected_version" ]; then
set_java_version "$selected_version"
else
echo -e "${RED}No version selected${NC}"
fi
else
set_java_version "$1"
fi
~/.zshrc への追記内容
oh-my-zsh の設定ファイルに以下を追記します。
# ============================================
# Java Version Switcher
# ============================================
jdk() {
if [ -f "$HOME/switch-java.sh" ]; then
source "$HOME/switch-java.sh" "$@"
else
echo "Error: switch-java.sh not found in home directory"
fi
}
初回セットアップ
新しいターミナルを開く前に一度だけ実行してください。
source ~/.zshrc
以降は新しいターミナルを開くだけで自動的に利用可能になります。
使い方
方法 1:バージョンを指定して切り替え
jdk 21
jdk 17
jdk 11
jdk 8
方法 2:インタラクティブモード
jdk
引数なしで実行すると、インストール済みの Java 一覧が表示されてバージョンを選択できます。
使用例
$ jdk 17.0.9
✓ Java version switched successfully!
JAVA_HOME: /Library/Java/JavaVirtualMachines/ibm-semeru-open-17.jre/Contents/Home
openjdk version "17.0.9" 2023-10-17
IBM Semeru Runtime Open Edition 17.0.9.0 (build 17.0.9+9)
Eclipse OpenJ9 VM 17.0.9.0 (build openj9-0.41.0, JRE 17 Mac OS X aarch64-64-Bit 20231017_458 (JIT enabled, AOT enabled)
OpenJ9 - 461bf3c70
OMR - 5eee6ad9d
JCL - 3699725139c based on jdk-17.0.9+9)
# JAVA_HOME が正しく設定されているか確認
$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/ibm-semeru-open-17.jre/Contents/Home
主な機能
- カラー表示で見やすい出力
-
JAVA_HOMEとPATHを自動設定 - 切り替え後に
java -versionを自動表示 - エラーハンドリング付き
- インタラクティブモードとコマンドライン引数の両方に対応
従来の方法との比較
| コマンド | |
|---|---|
| 従来 |
export JAVA_HOME= `/usr/libexec/java_home -v 17` && export PATH=$JAVA_HOME/bin:$PATH && java -version
|
| 新しい方法 | jdk 17 |
注意事項
-
macOS 専用です。
/usr/libexec/java_homeを使用しているため Linux / Windows では動作しません。 - 切り替えは現在のシェルセッションにのみ反映されます(新しいタブ・ウィンドウには引き継がれません)。
-
同じメジャーバージョンが複数インストールされている場合、バージョン番号が最も新しいものが選ばれます。
例えばjdk 8と指定すると、8.0.472と8.0.392が両方ある場合は8.0.472が選択されます。
特定のものを使いたい場合はフルバージョンで指定してください。# フルバージョンで明示的に指定 jdk 8.0.392 jdk 8.0.472 - 既存の
~/.zshrcがある場合は、内容を確認してからマージしてください。