ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

从JDK到Maven:环境变量配置与镜像仓库避坑指南

从JDK到Maven:环境变量配置与镜像仓库避坑指南 上周新同事入职领了台新电脑第一天就卡在装环境上。按网上一堆教程装完JDKjava -version能出结果可一敲mvn -version就报不是内部或外部命令。这种问题我见得太多了十有八九是环境变量PATH里少配了Maven的bin目录或者JAVA_HOME指错了位置。Java、Maven安装这事儿说简单是真简单解压完配个路径就行但说麻烦也真麻烦——版本怎么选、镜像仓库怎么配、本地仓库放哪、为什么明明本地有包却还是引不进来这些坑不踩一遍根本记不住。这篇就把我从零到一跑通Java和Maven的完整过程写清楚适合刚入手Java生态的新人也适合那些每次换电脑都要重新折腾一遍环境的老手。1. 装JDK之前先把版本和发行版选明白很多人一上来就搜Java安装其实Java这十几年的版本策略早就变了。Oracle从Java 8之后改成了半年一个版本真正适合生产用的只有LTS长期支持版本。目前项目里最主流的还是Java 8对应JDK 1.8因为大量老项目、老框架都构建在它之上稍微新一点的公司会直接上Java 17或者Java 21。如果你今天要新装环境我建议直接选Java 21原因很简单Spring Boot 3.x要求的最低版本就是17而21作为最新LTS生态兼容性已经足够成熟。1.1 发行版怎么选Oracle JDK还是OpenJDK先把这个争议说透。Oracle JDK从Java 8u211之后Oracle 11开始就不再免费用于商业用途了个人开发还好公司内部用就要留意授权问题。OpenJDK是Oracle JDK的开源底子功能几乎一致日常开发完全够用。现在市场上常见的免费发行版有Eclipse TemurinAdoptium项目出品社区认可度最高Amazon CorrettoAWS维护更新很及时阿里云Dragonwell对国内网络友好下载速度快Microsoft OpenJDK微软出品我自己的习惯是个人学习用Eclipse Temurin公司项目如果运维指定就用对应版本。国内网络环境下从Adoptium官网下载可能会慢可以走国内镜像或者用阿里云Dragonwell的下载页。1.2 下载完先确认目录结构JDK安装包有种形式一种是exe/msi安装向导一种直接是zip/tar.gz压缩包。我强烈推荐压缩包因为解压即用不需要安装程序往注册表里写东西卸载也干净。解压后你会看到这样的目录jdk-21/ ├── bin/ # java、javac、jar等可执行命令都在这 ├── conf/ # 配置文件比如security目录下的java.security ├── include/ # C/C头文件涉及JNI调用时需要 ├── jmods/ # JMOD模块文件构建jre用的 └── legal/ # 开源协议声明装完之后第一件事不是配环境变量而是先运行bin下的java -version确认解压出来的JDK能正常执行。这一步能排除包损坏和32位/64位不匹配的问题。1.3 平时根本碰不到的坑JAVA_HOME指向jre还是jdk旧版JDK在安装目录下面自带一个jre目录很多人配置JAVA_HOME时手滑指到了jre上。Java 9之后官方不再提供独立的jre目录所以现在这个问题少了但我还是见过有人把JAVA_HOME配到类似C:\Program Files\Java\jdk-21\bin的。这个一定要纠正JAVA_HOME必须指向JDK的根目录也就是包含bin目录的上一层不是bin本身也不是jre。2. 环境变量配置JAVA_HOME和PATH的配合逻辑环境变量配置是整个安装过程中最核心也最容易翻车的一步。很多人直接把JDK的bin目录写进PATH里用是能用但下次换个JDK版本就得去改PATH改错了又得折腾半天。正确做法是先用JAVA_HOME保存JDK根路径然后在PATH里引用JAVA_HOME形成改一个变量就能全局切换版本的结构。2.1 为什么必须配置JAVA_HOMEJAVA_HOME本身不是一个Java运行必须的变量但它是整个Java生态的约定。Tomcat、IDEA、Maven、Gradle这些工具启动时会主动去读JAVA_HOME找不到就报错。如果你只在PATH里写了java命令Maven虽然能通过PATH找到java但很多脚本内部还是习惯查JAVA_HOME查不到就会出现各种诡异问题。另外把JAVA_HOME单独提出来以后升级版本只需要改JAVA_HOME这一个值PATH里所有引用它的路径自动跟着变。2.2 Windows、macOS、Linux三种配置方式Windows下我推荐用图形界面配因为不容易出错右键此电脑 → 属性 → 高级系统设置 → 环境变量新建系统变量变量名JAVA_HOME变量值填JDK根目录比如D:\dev\jdk-21找到PATH变量编辑新增一行%JAVA_HOME%\bin注意Windows 10以上版本PATH是分行显示的不要加;分隔符了直接在列表里加macOS和Linux的做法更直白编辑~/.zshrcmacOS新默认或~/.bashrcexport JAVA_HOME/usr/local/jdk-21 export PATH$JAVA_HOME/bin:$PATH配置完执行source ~/.zshrc让变量生效。2.3 验证环境变量配置成功的标志配完一定不要急着装Maven先开一个新的终端窗口这点很重要旧窗口不会刷新环境变量依次执行java -version看到类似java version 21.0.2 2024-01-16 LTS的输出就对了。然后执行javac -version这个命令会输出Java编译器版本。很多人只测了java不测javac导致后来Maven编译项目时报javac: not found白折腾半天。再顺手验证一下JAVA_HOME本身echo %JAVA_HOME% # Windows echo $JAVA_HOME # macOS/Linux输出必须是JDK根目录路径后面不能有多余的空格和\bin。3. Maven下载与基础安装和JDK不同的地方Maven本质是一个构建工具它的安装过程和JDK几乎一样——下载压缩包、解压、配环境变量。区别在于Maven本身不运行什么程序它只是用Java写的一堆脚本所以它依赖JAVA_HOME而不是反过来。3.1 版本选择认准3.9.xMaven的版本命名和Java不一样没有LTS的概念但社区实际上把3.2.5、3.5.4、3.6.3这些版本当成了稳定到发指的版本。目前官方主推的是3.9.x系列它的父级版本跟3.8.x相差挺大对Java 8到Java 21的兼容性都做了修复。我在生产项目里用3.9.6和3.9.9都跑过没出过问题。网上偶尔能看到Maven 3.7下载之类的关键词实际上Maven官方从来没发布过3.7版本这多半是把Apache软件基金会其他项目的版本号记混了。选版本的原则很简单去Apache官方下载页看当前最新release选3.9.x而不是3.8.x别用SNAPSHOT版。3.2 Maven目录结构说明解压Maven后你会看到一个名为apache-maven-3.9.6的目录这是官方发布包的标准命名里面关键的目录是apache-maven-3.9.6/ ├── bin/ # mvn、mvn.cmd脚本 ├── boot/ # maven自己加载的类加载器 ├── conf/ # settings.xml全局配置文件 └── lib/ # maven运行时依赖的大量jar包conf/settings.xml是全局配置文件它控制着本地仓库位置、镜像源、代理、服务器认证等关键行为。这个文件在后面的实战中会反复折腾所以先记下它的位置。3.3 Maven的环境变量和验证JDK的JAVA_HOME配好后Maven需要的是MAVEN_HOME和PATH配置原理一模一样Windows新建系统变量MAVEN_HOME值为D:\dev\apache-maven-3.9.6PATH里新增%MAVEN_HOME%\binmacOS/Linux在.zshrc里加export MAVEN_HOME/usr/local/apache-maven-3.9.6 export PATH$MAVEN_HOME/bin:$PATH配置完新开窗口执行mvn -v正常输出里必须有Maven home、Java version、Java home三行信息。如果Maven home和Java version都能显示但最后一行Java home路径是错的那说明你JAVA_HOME没配对Maven虽然勉强能找到java命令但后续编译时很可能会报class错误。4. settings.xml实战本地仓库、镜像源与多仓库优先级Maven装完如果你什么都不动直接执行mvn help:system它会默认到用户目录/.m2/repository下建仓库然后去中央仓库下载一堆初始依赖。默认行为有两个问题一是国内访问Maven中央仓库经常抽风速度以KB为单位二是默认本地仓库放在C盘系统盘空间越来越紧张。这些都要通过改settings.xml来解决。4.1 第一个要改的localRepositorylocalRepository标签指定依赖jar包下载后存放的本地目录。我一般放D盘或单独的数据盘比如localRepositoryD:/maven-repo/localRepository注意两个细节路径不支持D:\maven-repo这样的反斜杠写法建议统一用正斜杠或者双反斜杠这个目录如果不存在Maven会自动创建不用预先建。改完本地仓库以后所有项目的依赖都从这个目录读磁盘空间不足时也能一眼看出哪块占得多。4.2 配置阿里云镜像仓库这是国内用户最需要的一步。Maven中央仓库repo.maven.apache.org服务器在海外下载速度慢是常态。配置镜像源的思路是让Maven不去中央仓库而是从阿里云的镜像同步依赖。在settings.xml的mirrors节点下加mirror idaliyunmaven/id namealiyun maven public/name urlhttps://maven.aliyun.com/repository/public/url mirrorOfcentral/mirrorOf /mirror这段配置的作用把所有中央仓库的请求都转发给阿里云。mirrorOfcentral/mirrorOf意思是只镜像Maven的central仓库不会影响后续你追加的第三方仓库。如果你还需要Spring、JBoss等单独的仓库阿里云有一个聚合地址https://maven.aliyun.com/repository/public它已经把central和jcenter都聚合进去了日常开发这一个地址就够用。4.3 多个镜像仓库的配置规则公司接入私服后settings.xml里会有多个mirror。这里有一个最容易踩的坑Maven对同一个仓库只认第一个匹配到的mirror后面的不会生效。举例说明mirrors mirror idaliyun/id urlhttps://maven.aliyun.com/repository/public/url mirrorOfcentral/mirrorOf /mirror mirror idcompany/id urlhttp://repo.company.com/repository/maven-public//url mirrorOf*/mirrorOf /mirror /mirrors如果company的mirrorOf是*匹配所有那阿里云那条配置就形同虚设因为所有仓库请求都优先命中了company。如果你的私服没有代理外部中央仓库的功能建议把私服的mirrorOf明确指向*然后让私服去同步中央仓库如果私服只放内部依赖外部依赖还是要走阿里云那就应该把company的mirrorOf限定为releases, snapshots这种内部仓库id。4.4 profiles里配置仓库而不是镜像镜像mirror解决的是请求转发给谁的问题仓库repository解决的是从哪些地址拉依赖的问题。两者很容易混。如果你的私服必须靠内部认证才能访问那更合理的做法是在profiles节点指定repositoriesprofile idcompany/id repositories repository idcompany-repo/id urlhttp://repo.company.com/repository/maven-public//url /repository /repositories pluginRepositories pluginRepository idcompany-plugin-repo/id urlhttp://repo.company.com/repository/maven-public//url /pluginRepository /pluginRepositories /profile注意plugin仓库和依赖仓库经常要分开配因为Maven默认的插件仓库是central如果你私服没同步插件索引很多构建插件会拉不到。5. 高频踩坑从.m2目录到依赖引用失败的完整排查链路配置全都弄对了不代表后面就不会遇到问题。这里把我在实际环境中碰到过的四个高频故障完整写一遍排查思路每一个都对应了热搜里的高频关键词。5.1 .m2目录下没有settings.xml怎么办新装Maven后用户目录下自动生成~/.m2但里面只有repository目录没有settings.xml。很多人误以为配置文件丢了其实这是正常现象。~/.m2/settings.xml是需要手动从Maven安装目录的conf/settings.xml复制过去的。复制一份到用户目录的目的是把全局配置变成用户级配置避免以后升级Maven时把自定义配置覆盖掉。操作方式cp /usr/local/apache-maven-3.9.6/conf/settings.xml ~/.m2/settings.xml复制完再改~/.m2/settings.xml里的localRepository和mirror配置。Maven读取配置的顺序是全局settings.xml先加载然后加载用户settings.xml用户配置会覆盖全局配置所以日常改用户级文件即可。5.2 本地仓库明明有jar包却还是报找不到依赖这是最让人抓狂的问题之一。现象是~/.m2/repository里能找到org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.jar但IDEA里跑项目时依然提示cannot resolve symbol或者编译失败。优先排查这三件事坐标是否写错。去本地仓库的目录结构里看路径路径里的目录层级就是groupId、artifactId的映射。比如org/apache/commons对应的groupId是org.apache.commons多一个点少一个点都会导致找不到。是否只下载了.jar没下载对应.pom文件或者.pom损坏。Maven通过pom文件解析依赖树缺pom几乎等于依赖不存在。解决方案是把该依赖对应的整个groupId目录从本地仓库删掉然后强制更新一次mvn -U clean install-U参数会强制检查远程仓库的最新版本把缺失文件重新下载回来。IDEA的索引缓存没刷新。IDEA的Maven面板中有个刷新按钮点一下重新导入很多时候引不进来只是IDE界面上的缓存问题命令行里mvn compile反而是通过的。5.3 编译报错找不到com.sun.image.codec.jpeg.JPEGCodec这个错误在Java 8项目里很常见但放到Java 15以上跑就会崩。根本原因是com.sun.image.codec.jpeg这个包在JDK早期版本里属于内部APIJava 9模块化之后默认不再对外暴露。排查过程是我从一版老代码里真实踩到的第一步看到报错先确认JDK版本java -version第二步在项目pom.xml里查maven-compiler-plugin配置的source和target第三步确认代码里是否直接import了com.sun.image.codec.jpeg解决方案有两个最稳妥的是替换成标准API比如用javax.imageio.ImageIO或者com.github.jai-imageio库。如果只是老代码短期过渡也可以给编译器加--add-exports java.desktop/com.sun.image.codec.jpegALL-UNNAMED但这只适合临时环境不建议带到生产构建配置里。5.4 Maven下载依赖速度缓慢甚至卡死如果你的settings.xml里已经配了阿里云镜像还是慢那就再查三件事确认镜像配置真的生效了。可以执行mvn dependency:resolve -X开启调试日志后搜索Downloading看实际下载URL是不是阿里云的地址。如果继续指向repo.maven.apache.org说明mirror配置没生效检查mirrorOf匹配规则。确认本地仓库路径没有权限问题。Windows下如果放在C:\Program Files目录下权限不足会导致每次下载都失败或极慢最好把仓库放到用户目录或数据盘。是不是有私有库在拖后腿。某些依赖直接从私服拉而私服没有缓存首次解析会极慢。这种情况要么在私服上做同步缓存要么在profile里单独配置外部代理地址。5.5 IDEA里的Maven配置和命令行不一致很多人遇到这种情况命令行mvn clean install跑得好好的IDEA一运行就报错。核心原因通常是IDEA使用的Maven版本和设置跟命令行不一致。IDEA设置里需要检查三处Maven home path必须指向你解压的Maven目录比如D:\dev\apache-maven-3.9.6不要用IDEA自带的Bundled MavenUser settings file指向~/.m2/settings.xml不要用默认的全局配置Local repository显示为本地仓库路径确认它读取到了settings.xml里的配置如果改完IDEA还是报错执行一次File - Invalidate Caches / Restart把IDE的缓存清掉再重新导入项目。IDEA的Maven索引有时候会非常顽固不重启不生效。6. mvn命令实操从clean install到依赖树排查Maven配置全部搞定后项目构建这块必须掌握几个核心命令它们能解决90%的日常问题。6.1 最常用的构建组合mvn clean install这条命令是最标准的全量构建流程clean清空target目录删除上一次编译的class文件install将项目打包并安装到本地仓库供其他模块引用单模块项目直接用就行。多模块项目里install命令会按依赖顺序构建所有模块这也是为什么很多人在根目录执行一条clean install就能全部打好的原因。6.2 跳过检查的两种方式构建老项目时经常碰到的报错是checkstyle、spotbugs或者测试用例失败导致构建中断。临时需要跳过的话mvn clean install -DskipTests mvn clean install -Dmaven.test.skiptrue两者区别在于-DskipTests是编译测试类但不执行测试用例-Dmaven.test.skiptrue是连测试代码都不编译。另外跳过静态检查通常用-Dcheckstyle.skiptrue要确认项目实际使用的是哪个插件。6.3 查依赖冲突的利器依赖冲突是Java项目最隐蔽的问题之一。两个库传递依赖了同一个jar的不同版本Maven默认采用最近声明优先但偶尔会踩到版本不兼容的雷。排查命令mvn dependency:tree这条命令会打印出整个依赖树。关键在于看有没有同一个groupId下出现两个不同version。比如com.fasterxml.jackson.core:jackson-databind:2.15.2 com.fasterxml.jackson.core:jackson-databind:2.17.1这种结局一般就是引入dependencyManagement把版本统一管起来。用mvn dependency:tree -Dverbose还能看到依赖是被哪条链路引进来的排查的时候多这层信息量就差很多。6.4 Maven命令行常用参数速查参数作用示例-U强制更新SNAPSHOT依赖和快照mvn compile -U-pl指定构建模块多模块项目mvn install -pl module-a-am构建指定模块及其依赖模块mvn install -pl module-a -am-DskipTests跳过测试执行mvn package -DskipTests-X打开调试日志mvn install -X-o离线模式不访问网络mvn compile -o离线模式在断网环境下很有用前提是之前已经完整下载过依赖。如果离线模式下报缺包那说明本地仓库没有该依赖切回在线模式跑一次再切离线。7. 安装完之后的健康检查清单环境装完我习惯按下面这套清单做一遍快速体检。这些检查项看着简单但能拦截掉日后80%的莫名其妙问题。java -version输出正常确认版本符合预期javac -version输出正常编译器可用echo $JAVA_HOME或echo %JAVA_HOME%指向JDK根目录mvn -v输出的Java home一行与JAVA_HOME一致mvn help:system能成功执行并下载初始化文件打开IDEA的Maven设置面板三处路径与命令行一致用mvn dependency:tree构建一个已有项目验证依赖解析正常这一步体检完了基本不会再出现配置半天最后才发现JDK版本不对的尴尬。如果一切正常下一步就进入业务开发了比如用Maven创建第一个Spring Boot项目。我个人在实际操作中的体会是Java和Maven安装这件事第一次花两小时捣鼓第二次十分钟以内就能搞定。关键在于把每一处配置背后的原因弄明白——为什么配JAVA_HOME、为什么改镜像、为什么本地仓库要单独放一块盘。这些都搞懂了后面无论换新电脑还是接手新项目都能用最快的速度把环境跑通。
返回列表