这段时间连续帮几个新同事配 Windows 开发机我又把整套 Java 环境搭建流程完整走了一遍Windows 下通过 WSL 安装 Ubuntu 24.04进系统后用 SDKMAN 管理 JDK再用 SDKMAN 装 Maven。这套组合我用了一年多中间踩过不少坑也优化过好几轮今天整理成一篇可以直接照着抄的操作总结。WSL 不是模拟器而是跑在 Windows 里的一个轻量级 Linux 环境WSL 2 用的还是真正的 Linux 内核命令行体验和服务器上的 Linux 几乎没差别。对在 Windows 上做 Java 后端开发、又需要贴近 Linux 环境联调的人来说这套方案是我目前用过最舒服的。文章不会只贴命令我会把每个关键步骤背后的理由、常见的坑、以及怎么验证是否真的装好了都讲清楚。如果你完全没接触过 WSL照着做也能把这套环境跑起来。1. WSL 2 与 Ubuntu 24.04为什么值得在 Windows 里装一个真 Linux1.1 我最终选择 WSL 2 而非虚拟机的三个理由早在 WSL 还只能跑命令行工具、不支持完整系统调用的时候我也用过 VirtualBox 和 VMware 装 Linux 虚拟机来做开发。虚拟机方案不是不能用但痛点很明显每次开机要先等虚拟机系统启动分配的内存和磁盘空间是固定的Windows 和 Linux 之间传文件要靠共享文件夹调试起来总觉得隔了一层。WSL 2 把这些麻烦基本都解决了。它是跑在轻量级虚拟机里的但启动速度接近秒开内存按需分配不需要你手动划一块固定内存给它。更关键的是WSL 2 和 Windows 的互操作做得很自然在 WSL 里可以直接执行 Windows 程序在 Windows 里也能通过\\wsl$路径访问 Linux 里的文件。这两个系统的边界对你来说是近乎透明的。还有一点是支持周期。Ubuntu 24.04 是 LTS 版本官方支持会持续到 2029 年软件源里的包版本也比较新。对开发机来说选 LTS 意味着不用频繁做大版本升级环境能稳定用很久。1.2 安装前的两个前置检查Windows 版本与虚拟化状态开始之前先确认两件事不然中途可能卡住。第一Windows 版本。WSL 2 要求 Windows 10 2020 年 5 月更新2004及以上版本Windows 11 全系都支持。按Win R输入winver回车就能看到系统版本号。如果版本太老先把系统更新到位再继续。第二CPU 虚拟化是否开启。WSL 2 需要虚拟化技术支撑。打开任务管理器切到“性能”选项卡选 CPU看右下角“虚拟化”是不是“已启用”。如果是“已禁用”需要进 BIOS 开启 Intel VT-x 或 AMD-V。这一步不做后面 WSL 2 会报错。确认没问题后用管理员身份打开 PowerShell执行两条命令启用必需功能dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart执行完重启系统。这一步的本质是把 Windows 的“WSL 功能”和“虚拟机平台”两个内核组件打开之后才能分发和运行 Linux 发行版。1.3 安装 Ubuntu 24.04 的两种路径与我的选择装 Ubuntu 有两条路。如果你能正常打开应用商店直接在商店里搜“Ubuntu 24.04”找到后点安装等它下载完就行。这是图形化操作最直观。但我实际更推荐命令行方式尤其是在公司电脑上应用商店经常被策略限制或者下载极慢。管理员 PowerShell 里执行wsl --install这条命令会默认安装最新版 Ubuntu同时自动启用需要的功能省心。如果想明确指定 24.04可以先看有哪些可用发行版wsl --list --online输出里找到Ubuntu-24.04之后执行wsl --install -d Ubuntu-24.04安装完成后从开始菜单打开 Ubuntu 24.04按提示设置一个用户名和密码。这里的用户名将来会作为 WSL 里的 Linux 用户也决定了你的家目录路径是/home/用户名密码用于sudo。都弄完以后用这个命令确认一下发行版版本wsl -l -v如果看到 VERSION 一列是 2说明走的 WSL 2万事大吉。如果是 1执行wsl --set-version Ubuntu-24.04 2把它升上去。2. Ubuntu 24.04 落地后的第一轮收尾配置2.1 更新软件源并升级系统基础包刚装好的 Ubuntu 24.04软件源快照是安装介质生成时的状态不一定最新。我建议一进去先做一次全量更新把系统补丁和软件包索引刷到最新sudo apt update sudo apt upgrade -yapt update只更新软件包索引不实际升级apt upgrade才是真正升级已安装的包。第一次升级的包数量可能不少耐心等它跑完。中间如果弹出一个蓝色的服务重启确认框直接选 OK 即可不影响后续操作。这一步我一般不跳过。一方面是为了安全补丁另一方面是后续要装编译工具和依赖索引越新能拿到的包版本越新坑越少。2.2 补装编译工具与常用依赖接下来安装这一套基础工具sudo apt install -y build-essential curl zip unzip git ca-certificatesbuild-essential包含 gcc、g、make 等编译工具链。也许你现在只是装 Java 工具链觉得不一定要它但后面经常会有从源码编译软件的情况缺了它真的很麻烦。curl是下载用的zip和unzip是 SDKMAN 安装脚本的硬性依赖git用来拉代码ca-certificates保证 HTTPS 连接正常。提前装齐后面每一步都畅通。这里有个小细节SDKMAN 的安装脚本在解压候选版本时依赖unzip如果你在一个极简环境里直接跑 SDKMAN 安装命令很可能卡在解压阶段才报错。所以这一步别省。2.3 在 WSL 里访问 Windows 文件与剪贴板的边界装好基础包后先搞清楚 WSL 和 Windows 之间文件互操作的基本规则后面能少走很多弯路。Windows 的 C 盘在 WSL 里被挂载在/mnt/cD 盘是/mnt/d以此类推。你可以用ls /mnt/c/Users/你的Windows用户名/Desktop直接访问桌面文件。反过来从 WSL 里也能调用 Windows 程序比如notepad.exe somefile.txt会用 Windows 记事本打开这个文件explorer.exe .会在 Windows 文件管理器里打开当前目录。剪贴板是双向共享的在 Windows 里复制文本切到 WSL 直接 CtrlShiftV 粘贴在 WSL 里复制Windows 侧也能粘贴出来。这个看似不起眼的特性实际用起来很爽。既然双方文件互访这么方便那我们把开发项目放在哪里这里我提前说一个结论项目文件千万别放在/mnt/c下。原因我在后面第 5 章会详细讲你只要记住开发项目放到 WSL 内部的~/workspace这类 Linux 目录里就对了。3. 用 SDKMAN 管理 Java 工具链环境治理的关键一步3.1 为什么不在系统层面直接安装 Maven很多人的习惯是先发现没 Maven然后sudo apt install maven装上完事。这个做法在只做一个项目、只有一个 JDK 版本的时候没问题但团队环境很快就失控。apt 源里的 Maven 版本往往不是最新JDK 也一样而且系统里同一时间只能有一个默认版本。我在之前一段时间就吃过这个亏手头一个老项目依赖 JDK 8另一个新项目要用 JDK 17系统里装了 apt 的 OpenJDK环境变量改来改去最后经常出现“这个项目能编、那个项目编译报错”的情况。后来换了 SDKMAN这种问题基本绝迹。SDKMAN 的本质是 Java 生态的版本管理器它把候选软件JDK、Maven、Gradle、Spring Boot CLI 等都隔离安装在~/.sdkman/candidates目录下每个版本一个独立文件夹。当前用哪个版本由current软链接决定。切换版本只是改个软链接和更新 PATH不碰系统目录卸载也只是删文件夹干净得很。用一个不恰当的类比SDKMAN 像是给 Java 工具链装了一个“软件管家”但它切换版本的能力比一般软件管家强得多。3.2 SDKMAN 安装脚本的前置依赖与执行细节确保前面装好了curl、zip、unzip然后执行curl -s https://get.sdkman.io | bash这里有个值得知道的细节脚本会把初始化代码追加到~/.bashrc。如果你是 bash 用户执行完新开一个终端就能用sdk命令如果不想重开终端手动执行一次source $HOME/.sdkman/bin/sdkman-init.sh验证一下sdk version正常会输出 SDKMAN 的版本号说明安装成功。如果提示找不到sdk多半是刚才的source没执行成功或者.bashrc加载顺序有问题。可以手动检查~/.bashrc末尾是否有一行类似THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!!的内容。3.3 SDKMAN 的版本切换原理与日常常用命令先看看能装哪些 JDKsdk list java输出会列出一大堆注意看每个标识符的命名规则厂商-版本号。比如21.0.4-temtem代表 Eclipse TemurinAdoptium 项目出品的构建。我一般优先选带tem或ms的版本前者是最常见的开源构建后者是微软构建。LTS 版本选 17 或 21 都行我装了 21sdk install java 21.0.4-tem sdk default java 21.0.4-teminstall负责下载安装default把这个版本设置为所有终端默认使用的版本。如果只是临时在当前终端切一下可以用sdk use java 21.0.4-tem。SDKMAN 切换版本的原理其实很朴素它在~/.sdkman/candidates/java下给每个版本建独立目录然后维护一个名为current的符号链接指向当前默认版本。当你执行sdk default它把current指向新版本同时把current/bin加入 PATH并设置JAVA_HOME指向current目录。这一切只对当前 Linux 用户生效不碰系统全局设置。4. Maven 安装、镜像配置与构建验证全流程4.1 通过 SDKMAN 安装 Maven 并确定默认版本装 Maven 前必须先有 JDK。Maven 本身是 Java 写成的它需要JAVA_HOME环境变量来定位 JDK。刚才 SDKMAN 已经把JAVA_HOME指到我们选中的 JDK 21 了现在直接装 Mavensdk list maven看列表里最新稳定版一般是 3.9.x 系列。安装并设为默认sdk install maven 3.9.9 sdk default maven 3.9.9用mvn -v验证你会看到类似这样的输出Apache Maven 3.9.9 Maven home: /home/你的用户名/.sdkman/candidates/maven/current Java version: 21.0.4, vendor: Eclipse Temurin, ...注意看Java version是不是 JDK 21。如果输出里显示的 Java 版本不对多半是 JAVA_HOME 出了问题对应第 5.2 节的内容。这里提醒一句如果你新项目要用 JDK 21Maven 版本最好在 3.9 以上。更早的版本对 JDK 21 的字节码版本识别不全编译时可能报一些奇怪的错误。4.2 settings.xml 的核心配置项与镜像选择Maven 有两层配置文件全局配置在 SDKMAN 安装目录下的current/conf/settings.xml用户级配置在~/.m2/settings.xml。用户级配置默认不存在需要自己创建它的优先级高于全局配置。我建议只动用户级配置文件这样升级 Maven 时配置不会丢。先看你的用户目录下有没有.m2目录mkdir -p ~/.m2 nano ~/.m2/settings.xml写入以下内容?xml version1.0 encodingUTF-8? settings xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd localRepository${user.home}/.m2/repository/localRepository mirrors mirror idaliyun/id namealiyun public mirror/name urlhttps://maven.aliyun.com/repository/public/url mirrorOfcentral/mirrorOf /mirror /mirrors /settingslocalRepository指定本地仓库位置Maven 下载的所有依赖都缓存到这里。mirror的作用是接管对中央仓库的访问。国内直接访问 Maven 中央仓库经常很慢镜像服务器会同步上游仓库的内容你从镜像拉依赖速度会快很多。我把mirrorOf写成central而不是*意思是只拦截对中央仓库的请求其他第三方仓库不受影响。这么做的好处是将来项目里配了特殊仓库不会被镜像无差别代理避免一些奇怪的下载失败。4.3 用真实项目验证 mvn clean package 全链路装好之后光看版本没意义得实际跑一个项目才算验收。我用 Maven 自带的原型插件生成一个最小 Java 项目mvn archetype:generate \ -DgroupIdcom.example \ -DartifactIddemo-app \ -DarchetypeArtifactIdmaven-archetype-quickstart \ -DinteractiveModefalse执行时 Maven 会下载插件和依赖到本地仓库第一次可能慢一些。看到BUILD SUCCESS后进入项目目录cd demo-app mvn clean package这段命令里clean清掉旧的 target 目录package依次执行编译、测试、打包。日志中会出现BUILD SUCCESS。最后检查产物ls -l target/你会看到demo-app-1.0-SNAPSHOT.jar说明整个链路已经通了。如果还不放心可以运行一下java -jar target/demo-app-1.0-SNAPSHOT.jar看到Hello World!输出环境就是完全可用的状态。5. 从零到可用我踩过的坑与给出的解决方案5.1 Maven 依赖下载慢或失败根因与修复最常遇到的问题是刚装完 Maven 跑构建时卡在下载依赖这一步或者直接报socket timeout、Connection reset。根因其实不复杂Maven 默认访问的中央仓库在海外网络链路长高峰期丢包严重。再加上某些网络环境下 HTTPS 握手也会被干扰下载自然不稳定。解决思路有两个方向。第一个方向是配置镜像也就是我上面写的settings.xml方案。把中央仓库请求代理到国内镜像服务器下载速度通常能快一个数量级。这也是我推荐的最省心方案。第二个方向是如果公司网络强制走 HTTP 代理需要在settings.xml里显式配置代理信息proxies proxy idhttp-proxy/id activetrue/active protocolhttp/protocol host代理服务器地址/host port8080/port username如果不需要认证就删掉/username password同上/password nonProxyHostslocalhost|127.0.0.1/nonProxyHosts /proxy /proxies我个人建议能走镜像就优先走镜像代理配置属于锦上添花只有在特定网络环境下才用得上。5.2 JAVA_HOME 与 PATH 错乱的典型表现和处理这是一个特别容易遇到、又特别隐蔽的问题。表现是java -version输出是 SDKMAN 装的 JDK 21但mvn -v显示的 Java 版本却是系统里另一个 JDK或者which java指向/usr/bin/java而不是~/.sdkman/candidates/java/current/bin/java。原因通常有三个一是不小心用 apt 装过 OpenJDK/usr/bin/java被系统包占用了二是 SDKMAN 的初始化代码写在.bashrc末尾但系统全局的JAVA_HOME在/etc/profile或/etc/profile.d里被提前设置优先级把 SDKMAN 盖过了三是 IDE 或脚本里硬编码了绝对路径。排查顺序我总结成一套echo $JAVA_HOME which java ls -l /usr/bin/java 2/dev/null tail -n 20 ~/.bashrc先看当前终端里JAVA_HOME指向哪再看java软链接来源。如果是/usr/lib/jvm开头的路径基本可以确定是 apt 装了系统 OpenJDK。处理方式很简单sudo apt remove openjdk-*然后确认 SDKMAN 的初始化代码还在重新执行sdk default java 21.0.4-tem最后开一个新终端验证echo $JAVA_HOME java -version mvn -v三处输出的 JDK 版本必须一致。这是我验证环境是否干净的硬指标。5.3 跨文件系统读写导致的构建性能陷阱最后一个坑和性能有关。第一次用 WSL 时我习惯性地把项目放在了 Windows 侧的路径下比如C:\Users\我的名字\code在 WSL 里对应/mnt/c/Users/我的名字/code。结果跑mvn clean package比在纯 Linux 环境慢了不止一倍小文件多的操作更是明显卡顿。原因是 WSL 2 访问 Windows 的 NTFS 磁盘走的是 9P 协议这个路径上的文件 I/O 损耗很大尤其是大量小文件读写。Maven 构建时要扫描、生成成千上万个文件这个损耗会被无限放大。而 WSL 内部自己的文件系统是 ext4性能是接近原生 Linux 的。解决方式也简单项目一律放 Linux 侧。我习惯建~/workspace目录所有代码都扔进去。那么问题来了代码放 WSL 里Windows 上的 IDE 怎么编辑方法是在 Windows 文件管理器地址栏输入\\wsl$\Ubuntu-24.04\home\你的用户名\workspace这样就可以像访问普通文件夹一样访问 Linux 里的项目。或者更推荐的做法是使用支持 WSL 远程开发的编辑器比如 VS Code 的 WSL 扩展直接在 WSL 环境里做开发既享受 Linux 文件系统性能又保留图形化编辑体验。我现在已经养成习惯只要是在 WSL 里跑构建的项目文件一定放 Linux 侧。Windows 侧只保留安装包和文档这类不涉及构建的文件。如果你完整走完上面这些步骤现在你已经拥有一个干净的 Ubuntu 24.04 环境SDKMAN 帮你管着 JDK 和 Maven 的版本镜像配置让依赖下载顺畅项目也跑通了构建。我后来每次换电脑基本就是重复这套流程半小时左右就能恢复到一个顺手的开发环境。如果你照着做的时候在某个环节卡住回头看看对应的排查小节多半能找到原因。