最可靠轻量的多jdk切换方式是update-alternatives,需同时注册java与javac、验证路径有效性、手动同步java_home,并三处版本(java -version、javac -version、$java_home)一致才真正生效。

update-alternatives 是 Linux 下最可靠、最轻量的多 JDK 版本切换方式,不用装额外工具(如 sdkman),不改 shell 配置文件,也不依赖用户级别别名。但必须同时注册 java 和 javac,否则编译和运行会用错版本。
先确认 JDK 安装路径是否真正可用
别急着注册,很多问题根源在路径本身无效:
• /usr/lib/jvm/jdk-17.0.14+8/bin/java 必须存在且可执行(ls -l 看权限,./java -version 能输出)
• 手动解压的 JDK 常见错误:路径里带空格、漏了 bin/、解压不完整(比如没解出 javac)
• CentOS/RHEL 默认路径是 /usr/lib/jvm/java-17-openjdk-*,而 Temurin/Adoptium 解压后路径含 + 或 _,复制时别手抖删掉
必须分开注册 java 和 javac
update-alternatives 不管“JDK 整体”,只管单个命令软链。如果只注册 java,javac 还留在旧版本,mvn compile 就会报 Unsupported class file major version。
• 每个 JDK 版本都要执行两条命令:
sudo update-alternatives --install /usr/bin/java java /path/to/jdk/bin/java 170
sudo update-alternatives --install /usr/bin/javac javac /path/to/jdk/bin/javac 170
• 优先级数字(如 170)只影响默认选中项,不影响能否切换;只要注册成功,--config 就能手动选
• 注册前确保目标路径(如 /usr/bin/java)不是已存在的硬链接或文件,否则会报 link path already exists
切换后 JAVA_HOME 不自动同步
update-alternatives --config java 只改 /usr/bin/java 的软链,完全不碰 JAVA_HOME。而 mvn、gradle、IDEA 后台进程全靠 JAVA_HOME 决定用哪个 JDK 编译。
• 临时修复:export JAVA_HOME=/usr/lib/jvm/jdk-21.0.4+7(路径必须和你刚选的 java 实际路径一致)
• 长期方案:在 /etc/profile.d/java.sh 里定义函数,例如:
jdk21() { export JAVA_HOME=/usr/lib/jvm/jdk-21.0.4+7; export PATH=$JAVA_HOME/bin:$PATH; }
• 验证是否真同步:
java -version 和 echo $JAVA_HOME 输出的主版本号必须一致,否则构建工具大概率出错
验证切换是否真正生效
光看 java -version 不够,要三处一致才安全:
• java -version → 运行时版本
• javac -version → 编译器版本
• echo $JAVA_HOME → 构建工具依赖的根路径
• 额外建议跑一次 mvn -v 或 gradle -v,确认它们显示的 Java 版本和上面三项完全匹配
• 如果不一致,说明环境变量没刷新,或者你用的是非登录 shell(比如 VS Code 终端没 reload profile)
JAVA_HOME 和 update-alternatives 两套机制各自为政」——系统命令走软链,构建工具认环境变量,两者不同步,就是静默失败的源头。











