多 jdk 并存时的安装来源、版本切换、java_home 与构建工具对齐方式,以及 linux、macos、windows 下的常见选型。
问题边界:四类能力
| 能力 | 说明 | 典型载体 |
|---|---|---|
| 获取 jdk 二进制 | 下载安装包或从包索引安装 | 发行方站点、包管理器、sdk install |
| 多版本并存 | 磁盘上同时保留多个 jdk | 上述安装方式的组合 |
| 切换默认 jdk | 改 path / java_home 或 shell 钩子 | jenv、jabba、sdkman、手动 |
| 按项目锁定版本 | 进入目录自动或显式选用某版本 | .java-version、.sdkmanrc、toolchains |
理清需求后再选工具,可避免「装得上但切不动」或「能切但与 ide/ci 不一致」。
工具总览与适用场景
| 工具/方式 | 主要作用 | 典型平台 | 备注 |
|---|---|---|---|
| sdkman | 安装与切换多版本 jdk,并可管理 maven、gradle 等 | macos、linux;windows 需 wsl 等 bash 环境(见官方安装说明) | 个人与团队都常用 |
| jenv | 管理已安装的多个 jdk,负责切换与 java_home 插件 | macos、linux 为主 | 不负责下载 jdk |
| jabba | 跨平台安装、切换 jdk | windows、macos、linux | 原仓库已长期停更,优先关注社区延续仓库(见 jabba) |
| homebrew | 通过 formula 安装 openjdk@xx 等 | macos(及 linuxbrew) | 多版本共存常配合 jenv 或手动 path |
| winget / scoop / chocolatey | windows 上安装与升级 jdk | windows | 与 jabba 或手动配置组合 |
| asdf / mise | 插件式多语言版本管理(含 java 插件) | 依插件与平台而定 | 适合多语言栈统一用一套命令 |
| 手动 path / java_home | 完全可控,无额外工具 | 任意 | ci、容器、受限环境常见 |
| maven toolchains | 按构建指定 jdk 路径,与 shell 默认 jdk 解耦 | 任意 | 与上游工具链配合 |
选型决策流程

sdkman
定位:在 bash 环境下安装、列出、切换候选版本(含 java 与常见构建工具)。
安装(摘自官方流程,以 sdkman.io/install 为准):
curl -s "https://get.sdkman.io" | bash source "$home/.sdkman/bin/sdkman-init.sh" sdk version
常用命令:
sdk list java sdk install java <identifier> sdk use java <identifier> sdk default java <identifier> sdk current java sdk uninstall java <identifier>
windows:官方以 wsl 或兼容 bash 的环境为适用前提;生产环境以当前安装页说明为准。
jenv
定位:在已安装多个 jdk 的前提下,管理使用哪一套(含全局、目录级、当前 shell),并通过插件维护 java_home。
安装(macos 常见):
brew install jenv # 将 jenv 初始化写入 ~/.zshrc 或 ~/.bashrc,例如: # eval "$(jenv init -)"
常用命令(以 jenv 文档 为准):
jenv add /path/to/jdk/home jenv versions jenv global <version> jenv local <version> jenv shell <version> jenv enable-plugin export
说明:jenv add 指向的是 jdk 根目录(内含 bin/java)。启用 export 插件后便于与 ide、maven 等读取的 java_home 对齐。
jabba
定位:类「多版本安装器 + 当前 shell 切换」,支持从远端索引拉取 jdk。
维护状态:原 shyiko/jabba 仓库已长期无活跃维护;实际选型请以 github 上社区延续组织 的发布页与安装脚本为准(例如 jabba-team 名下仓库),安装命令以前述仓库的 readme 为准,勿照抄过期博文中的固定 url。
概念级用法(具体子命令以所选 fork 文档为准):
列出远端可装版本 → install → use(当前 shell)→ alias default(默认) 项目级:部分实现支持在仓库根写入配置文件以自动选用版本
操作系统包管理与商店
homebrew(macos)
brew search openjdk brew install openjdk@17 /usr/libexec/java_home -v
多版本并存时,常用 /usr/libexec/java_home 与 jenv 组合;或用 brew link --overwrite 调整默认链(注意对系统其他 java 消费者的影响)。
windows:winget
winget search openjdk winget search temurin winget install eclipseadoptium.temurin.17.jdk
具体 id 以 winget search 结果为准。
windows:scoop / chocolatey
scoop bucket add java scoop install openjdk17
choco install temurin17jdk
包名与版本号随仓库更新而变化,安装后仍需在「系统/用户环境变量」或 shell 配置中统一 java_home 与 path 优先级。
asdf 与 mise
定位:用统一插件模型管理多语言运行时;适合同一台机器上除 java 外还要切 node、python 等版本的场景。
- asdf:需安装 asdf-java 插件(或社区替代插件),再
asdf install java ...。 - mise(原 rtx):见 mise 文档,支持声明式
mise.toml/.tool-versions。
两者与 jenv、sdkman 可能叠用,注意同一 shell 会话里谁最后改写 path,避免「装了但 java -version 仍指向旧版本」。
手动配置 path 与 java_home
适用:容器镜像、ci、受限桌面、或仅临时切换。
linux 示例(debian/ubuntu 安装 openjdk 17 后推断 java_home,勿使用错误嵌套括号):
sudo apt update sudo apt install -y openjdk-17-jdk java_home="$(dirname "$(dirname "$(readlink -f "$(command -v java)")")")" echo "$java_home" java -version
也可用 java -xshowsettings:properties -version 2>&1 | grep 'java.home' 核对 jvm 报告的 home 路径。
macos:优先 /usr/libexec/java_home 输出路径,再写入 shell 配置或 ci 变量。
windows:在「系统属性 → 环境变量」中设置 java_home 指向某 jdk 根目录,并把 %java_home%\bin 置于 path 较前位置。
maven toolchains
定位:在不依赖 shell 默认 java 的前提下,为 maven 构建指定 jdk(与不同模块、不同插件需求配合)。
在 ~/.m2/toolchains.xml 中声明多个 jdk 工具链,pom.xml 中通过 maven-toolchains-plugin 等绑定使用。适合「本机默认仍是 jdk 11,但某模块必须用 17」一类场景。细节以 apache maven toolchains 为准。
企业内统一开发环境
部分团队在统一 devops 或研发效能平台上集中规定各项目所用 jdk 版本,并与代码仓库、流水线、本地 agent 或 ide 配置联动。此类方案侧重流程与合规,与个人电脑上的 jenv/sdkman 互补:前者保证「团队口径一致」,后者保证「本机多项目灵活切换」。
具体能力与操作方式以各组织内部文档为准,本文不展开单一厂商产品名。
常见问题与排查
| 现象 | 可能原因 | 处理方向 |
|---|---|---|
| java -version 与预期不符 | path 上另有靠前 java | which -a java(unix)或 where java(windows)排查顺序 |
| ide 编译版本与终端不一致 | ide 使用内置 jre 或未指向同一 jdk | 在 ide 中显式设置 project sdk / gradle jvm |
| maven 用了「错的」jdk | java_home 或未使用 toolchains | mvn -v 查看 java home;必要时上 toolchains |
| jenv 切换无效 | 未 jenv init 或未启用 export 插件 | 按官方文档检查 shell 钩子等 |
| wsl 与 windows 各装一套 java | 两套环境变量隔离 | 在各自环境内单独配置,避免混用路径 |
免责声明
- 各工具安装脚本、包名、发行版标识符会随上游更新而变化,以官方文档与仓库 readme 为准。
- 文中命令为通用示例,在复制到生产或 ci 前请在目标环境实测。
参考链接:
- sdkman! 安装与用法
- jenv
- eclipse temurin(adoptium)
- apache maven toolchains
- mise
- asdf
- homebrew
- winget 文档(microsoft learn)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论