简介:OpenJDK 21 Windows x64 压缩包是一份面向64位Windows用户的Java开源开发环境,满足在Windows 64位环境下快速获取最新JDK构建的需求,适合希望跟进最新Java进展的开发者下载体验。包内提供了JDK运行与编译所需的核心组件,并附带模块描述、许可声明、安全策略等辅助文件,可帮助用户合规、高效地搭建测试环境,验证JDK增强提案中的新特性。资源共484个文件,以动态链接库、模块文件、可执行工具和许可文件为主,压缩后约189.2MB,整体结构清晰,便于按需取用。当前已有571人学习下载,多用于个人开发或技术预研;由于21版本仍处于早期访问草案阶段,不属于长期支持版本,追求生产稳定性的用户可优先选择正式发布版本。对想提前接触Java新功能的开发者来说,这份压缩包提供了直接上手的完整环境。
1. 从 JDK 8 直接跨到 OpenJDK 21:Win x64 上的一次真实迁移开场
手头一个跑了六七年的老服务,一直躺在 JDK 8 上。最近因为虚拟线程和 ZGC 实在馋得慌,决定在 Windows x64 的开发机上把 OpenJDK 21 装起来,顺便把构建脚本、IDE 和 Maven 配置全捋一遍。折腾完发现,真正花时间的不是解压和配环境变量,而是理解 21 跟 8 的差异、选择 zip 还是 msi,以及踩完环境变量和编译版本的一堆坑。这篇笔记就是给你在 Win x64 上装 OpenJDK 21 的准备清单、操作步骤和常见问题。
2. 先分清你要的“OpenJDK 21”:构建来源、包类型与选型对比
2.1 OpenJDK 21 到底是什么:版本号、LTS 与 API 边界
OpenJDK 21 是长期支持版本,按照 Java 的版本发布策略,21 会拿到持续多年的稳定更新,不是那种半年就让位给下个版本的短期特性版。对 Windows 64 位系统来说,你看到的是 win x64 的包,解压后得到一个完整 JDK,里面包含 java、javac、jar、jlink、jmods 这些工具和模块化运行环境。
版本号规则上,21 对应的 Java 版本字符串是 21.0.x。例如运行java -version会输出类似openjdk version "21.0.x"的内容。需要注意的是,不同发行版在 product 信息里会写明 vendor,这会影响默认 JVM 参数、许可证和后续更新渠道。也就是说,同样写着 OpenJDK 21 的包,实际运行行为可能在垃圾回收策略或安全属性上有细微差别。
API 边界上,21 引入了虚拟线程、记录模式、增强的 switch 模式匹配、字符串模板预览等新特性。对老项目来说,最大的冲击不是新语法,而是从 JDK 9 就开始的模块系统在 21 里已经完全常态化,--release参数比老的-source/-target更安全。理解这一点再装,才不会被项目里报的“模块找不到”或“class file has wrong version”吓到。
2.2 Windows x64 上的三种安装包:zip、msi、源码包怎么选
OpenJDK 21 在 Windows x64 平台常见的下载包有三种:免安装 zip、安装程序 msi、以及源码包。不同场景的选择标准差别很大,这里给出一张我常用的对比表。
| 包类型 | 文件格式 | 适合场景 | 主要注意点 |
|---|---|---|---|
| zip | .zip | 便携部署、CI、本机多版本切换 | 需要手工配置环境变量,升级直接换文件夹 |
| msi | .msi | 普通开发机安装、集成系统服务 | 会写注册表,卸载时残留项不好清理 |
| 源码包 | .tar.gz / .zip | 自定义模块、调试 JDK、给上游提补丁 | 构建耗时长,需要额外工具链和网络准备 |
我一般开发机用 zip 包,因为可以在 D 盘放多个 JDK 版本,需要切换时只改 JAVA_HOME 一处。团队里有人喜欢 msi,装完不用关心 PATH 顺序,但一旦同时装多个版本,系统环境变量会变得很乱,反而不如 zip 好控制。CI 服务器上我倾向于 zip,每个流水线任务都可以干净地解压到自己的工作目录,不污染共用机器。
如果你拿到的是源码包,请先想清楚目的。除非你要改 JDK 内部实现,或者需要为某个模块打补丁,否则在 Windows 上从源码构建 Web 版属于性价比很低的操作,单是编译一遍就可能吃掉半小时到一个小时,还容易因为本地没装对应工具链而翻车。
2.3 用命令行一键核对构建信息:版本、厂商与 JVM 参数
下载完包,先别急着写代码,先用两条命令把构建信息看清楚。这个习惯能省掉很多后面排查环境的血泪时间。
java -version java -XshowSettings:properties -version第一条输出版本号、构建编号和运行时名称,第二条会输出一组系统属性,包括java.home、java.vm.name、java.vendor、os.arch等。逻辑说明:-XshowSettings:properties是 JVM 的诊断开关,执行时会打印当前运行环境的真实属性,比盯着where java判断“到底用的是哪个 JDK”更直接。参数说明:如果只想看某个属性,可以结合os.arch过滤,但没必要过度加工,直接全量输出再扫一眼就够。
对新手来说,这一步能验证你拿到的到底是不是 Win x64 的包,别下了 x86 或 ARM 版本。如果os.arch显示的不是 x64,后续编译产物的内存布局和本地库支持都会受影响,尤其在使用 JNI、JNA 或者一些二进制加密工具时会突然蹦出一堆异常。
3. 把 OpenJDK 21 落到磁盘:目录结构、环境变量与项目配置
3.1 解压与安装:最小化安装步骤与目录约定
从 zip 包安装,目录尽量选一个没有空格的路径,比如D:\jdk\jdk-21。不要放进C:\Program Files,那会让你配 JAVA_HOME 时多踩一个引号坑。完整步骤是:先建目录,再解压,然后确认bin是不是在 JDK 根目录下。
mkdir D:\jdk tar -xzvf openjdk-21-windows-x64.tar.gz -C D:\jdk dir D:\jdk\jdk-21\bin逻辑说明:tar在 Windows 10 之后的系统里可直接用,也可以用解压软件。关键是保证bin目录与java.exe在同一级。很多人把bin目录当成 JAVA_HOME,导致%JAVA_HOME%\bin\java.exe变成bin\bin\java.exe。上面命令的最后一步就是为了确认目录结构没有多包一层。参数说明:-xzvf里的 z 表示 gzip 解压,v 输出过程,f 指定文件。如果你下的是 zip,把命令换成unzip openjdk-21-windows-x64.zip -d D:\jdk即可。
解压完成后可以再看一眼conf、legal、jmods等目录是否完整。jmods目录在后续使用 jlink 时会用到,千万不要为了省空间删掉;legal里放着许可证信息,公司环境里交付完整 JDK 时最好保留。遇到磁盘空间紧张,建议优先清理旧版本 JDK,而不是对当前 JDK 动刀。
3.2 JAVA_HOME 与 PATH 配置:两种方式与参数说明
配置环境变量有两种常用方式:永久写入用户级变量和临时写入当前会话。永久方式用setx,临时方式用$env:或set。我一般会先在 PowerShell 里确认路径,再写进用户级环境变量,避免把系统 PATH 搞坏。
setx JAVA_HOME "D:\jdk\jdk-21" setx Path "D:\jdk\jdk-21\bin;$env:Path"注意setx写入的是用户环境变量,写入的值会保留引号,而$env:Path在 PowerShell 被展开后会变成一大长串。所以更稳妥的做法是只设置JAVA_HOME,然后把%JAVA_HOME%\bin追加到 PATH。在 cmd 里的写法是:
setx JAVA_HOME "D:\jdk\jdk-21" setx Path "D:\jdk\jdk-21\bin;%JAVA_HOME%\bin"逻辑说明:JAVA_HOME是给 Maven、Gradle、IDE 等工具用的,它们会通过这个变量定位 JDK。PATH里的bin是给命令行解析 java/javac 用的。如果JAVA_HOME末尾带斜杠或引号,某些 Windows 原生工具会报路径错误,启动后先echo $env:JAVA_HOME看一下。参数说明:setx设置的值只对新开的进程生效,当前终端不会立刻读到,所以改完要重开一个窗口再测试。如果你只是想临时快速验证,用$env:JAVA_HOME = "D:\jdk\jdk-21"这样只在当前窗口生效。
3.3 用 Maven/Gradle 绑定 JDK 21:toolchain 与 compiler 参数
环境变量配完,还要让构建工具明确知道用 JDK 21。很多项目本地编译用的 JDK 和命令行 java 不是同一个,导致代码在 IDE 里跑得好好的,一到命令行构建就报版本错。Maven 里推荐配置 toolchain,这样即使机器上还有别的 JDK,也能指定 21。
<toolchains> <toolchain> <type>jdk</type> <provides> <version>21</version> <vendor>openjdk</vendor> </provides> <configuration> <jdkHome>D:\jdk\jdk-21</jdkHome> </configuration> </toolchain> </toolchains>逻辑说明:这段配置放在用户主目录下的.m2/toolchains.xml里,provides.version写 21,jdkHome指向实际解压路径。Maven 每次编译会优先匹配这个 toolchain,而不是系统里随便一个 java。参数说明:vendor不要省略,否则同时装多个发行版时会匹配错。如果项目还依赖 org.codehaus.mojo 的 toolchains 插件,需要确认插件版本支持 3.0.0 以上的 JDK。
Gradle 里的写法更省事,直接在构建脚本里指定 toolchain:
java { toolchain { languageVersion = JavaLanguageVersion.of(21) } }在 javac 层面,编译老项目时建议用--release 21,而不是-source 8 -target 8。--release会强制使用 21 的公共 API 集合,避免你用了 JDK 内部包,导致运行时在其他环境下找不到类。参数说明:如果团队还在用低版本 Maven compiler plugin,记得升级到支持 release 参数的版本,否则--release会被忽略,然后你会在完全不知情的情况下编译出另一个字节码版本。
4. 避坑排查:从“java 不是内部命令”到类加载异常
4.1 常见问题:版本不对、环境变量失效
现象:在命令行输入java -version提示“java 不是内部或外部命令”,或者正常运行后显示的版本还是 JDK 8/11,而不是刚装的 OpenJDK 21。
原因:PATH 里没有指向新 JDK 的 bin 目录,或者有其他 JDK 的 bin 排在前面。Windows 启动进程时会按 PATH 顺序找第一个匹配项,如果之前的 JDK 8 路径还在,java 命令自然被劫持。
解决:先执行where java,看解析到哪个程序;再确认C:\Windows\System32下面没有残留的旧的 java.exe;最后检查JAVA_HOME是否为D:\jdk\jdk-21。修正后重开终端再试一次。我一般会同时执行echo $env:JAVA_HOME和java -version,看到版本对上才继续。特别提醒:某些安全软件会往 PATH 里注入自己的 java 环境,这种属于环境变量之外的锅,平时不容易发现。
4.2 路径含空格与符号:Program Files 引发的玄学
现象:java命令能执行,但 IDE 或 Maven 启动时报“找不到 java.dll”或“Could not create the Java Virtual Machine.”,反复重装没效果。
原因:JDK 被装进了C:\Program Files\Java\jdk-21,路径里有空格,某些 Windows 原生命令或脚本没加引号,把C:\Program当成了程序名。这个问题看起来神神叨叨,实际就是 shell 解析的锅。
解决:把 JDK 解压到D:\jdk\jdk-21这种无空格路径;如果实在要用Program Files,必须在所有使用${JAVA_HOME}的配置里加双引号。我见过最典型的情况是某个 IDE 能识别 JDK 路径,但启动服务时执行了一个自己拼接的命令行,路径没加引号,结果报错信息里带着一长串被截断的路径。遇到这种情况,先检查注册表残留项和 Windows 环境变量列表里的最终值,不要只看 IDE 面板。
4.3 编译目标版本与实际运行版本不一致
现象:javac编译时没有报错,运行时抛出UnsupportedClassVersionError,后面跟着一段类似unsupported major version 65的话。
原因:编译用了 JDK 21 的默认字节码版本,而运行环境还是 JDK 8/11,类文件版本号对不上。类的 major version 65 对应 Java 21,低版本 JVM 不认这个数字。这种问题最容易出现在多版本共存的环境里,尤其是同事电脑上装了两个 JDK,构建工具拿到的是旧的。
解决:先确认运行端的java -version是 21;再用javap -verbose 类名看 class 文件里的 major version;如果项目需要兼容旧环境,就把编译参数改成目标版本,而不是只改-source/-target。我一般会在 Maven 的maven-compiler-plugin里显式写release,这样 IDE 和命令行统一编译参数,就不会出现两边各自为政的奇景。
4.4 类加载与模块化问题:java.base 模块找不到
现象:启动项目时出现“模块 java.base 不可见”或ClassNotFoundException里出现 java.lang 相关类,尤其是在使用了jlink或自定义 module-path 的场景里。
原因:JDK 9 之后的运行环境是模块化的,如果你手工删了jmods目录,或者用jlink裁掉了某些模块,Java 工具找不到基础运行模块。很多所谓“精简 JDK”的教程让你删jmods或src.zip来省空间,这在 OpenJDK 21 上尤其危险,因为jlink依赖jmods生成自定义镜像,删了之后后续所有模块化相关动作都会失效。
解决:不要动%JAVA_HOME%\jmods目录;如果是在自己生成的 runtime image 里跑,检查镜像里是否存在release文件;用java --list-modules查看当前基础模块列表。当你的依赖项使用了不被包含的模块时,最简单的方式是不用 jlink 精简镜像,直接用完整 JDK 启动。确有精简需求时,用jdeps分析出项目实际需要的模块,再把那些模块加进--add-modules,而不是凭感觉乱裁。
5. 用 jlink验证安装并裁一个最小运行镜像:白盒确认比命令行更可靠
验证 OpenJDK 21 是否真正可用,我习惯不跑大项目,而是先用 JDK 自带的jlink生成一个最小的运行时镜像,再对这个镜像执行java -version。这样能同时验证 JDK 模块完整、jlink 可用、路径配置正确,还能拿到一个体积更小的运行环境,一举三得。
D:\jdk\jdk-21\bin\jlink --add-modules java.base,java.logging --output D:\jre-mini D:\jre-mini\bin\java -version--add-modules指定保留的模块,--output指定镜像目录。这里只保留java.base和java.logging,生成的目录会比完整 JDK 小不少。逻辑说明:java.base是 JVM 运行的基础模块,java.logging是很多框架默认依赖的日志模块。如果你的项目要用 JVM 的一些高级特性,比如安全管理器或动态代理,还需要额外模块,但这个最小镜像已经足够验证安装。参数说明:--add-modules可以用逗号分隔多个模块;--output目录如果不存在,jlink 会主动创建,不需要提前建好。
执行成功后,把这个镜像目录复制到另一台没有完整 JDK 的 Windows x64 机器上,也能直接跑,前提是目标系统同样是 x64。这样你不需要给每台机器装完整 JDK,就能交付一个相对干净的应用运行环境。如果你担心小项目用不到所有模块,可以用jdeps分析自己的 jar 包依赖,再按结果选出需要的模块:
D:\jdk\jdk-21\bin\jdeps --module-path D:\jre-mini --print-module-deps your-app.jarjdeps输出的是当前依赖模块清单,拿这个结果回填到jlink --add-modules里,就能生成贴合项目的最小镜像。这个习惯我一直保留:解压完新 JDK,先跑一遍 jlink 最小镜像流程,再回到项目里构建。直到现在,我每次升级 JDK 都强制走一遍这个小验证,把“环境变量应该没问题”这种想法彻底改成“用结果说话”。希望这个步骤和前面那些踩坑记录能帮到你,省下你在 Windows 上折腾 OpenJDK 21 的时间。
本文还有配套的精品资源,点击获取