
剛開(kāi)始用Maven時(shí)我以為在Windows上裝好就是下載、解壓、配環(huán)境變量然后敲幾個(gè)命令完事。結(jié)果第一次在一臺(tái)新電腦上配置卡了快一上午。后來(lái)發(fā)現(xiàn)不是下載的包不對(duì)而是JAVA_HOME被配成了JRE的路徑Maven死活起不來(lái)。這篇文章就把整個(gè)Windows下Maven安裝和使用的過(guò)程完整整理一遍從版本選擇、環(huán)境變量、settings.xml到第一個(gè)項(xiàng)目的完整構(gòu)建流程以及幾個(gè)非常容易踩的坑給同樣準(zhǔn)備入門(mén)的讀者參考。這種環(huán)境安裝類的事情網(wǎng)上教程很多但大多是“照著敲能跑、換個(gè)環(huán)境就不行”。我希望這篇文章能讓你明白每一步在做什么、為什么要這么做這樣遇到問(wèn)題時(shí)不至于兩眼一抹黑。1. Windows下裝Maven前先把這幾個(gè)底層問(wèn)題想清楚1.1 Maven不是“裝個(gè)包”而已很多初學(xué)者的第一反應(yīng)是Maven就是用來(lái)下載依賴的工具。這個(gè)理解沒(méi)錯(cuò)但不完整。Maven真正解決的是構(gòu)建流程的標(biāo)準(zhǔn)化問(wèn)題項(xiàng)目用什么目錄結(jié)構(gòu)、編譯用哪個(gè)JDK版本、測(cè)試怎么執(zhí)行、最終打成JAR包還是WAR包這些繁瑣的事情通過(guò)一套約定就能統(tǒng)一處理。把Maven裝好意味著你的項(xiàng)目從源代碼變成可運(yùn)行產(chǎn)物的完整生命周期有了可復(fù)現(xiàn)的腳本。團(tuán)隊(duì)里任何一個(gè)人拿到項(xiàng)目執(zhí)行同一套命令就能得到同樣的結(jié)果。這也是為什么Java項(xiàng)目幾乎都會(huì)配一個(gè)pom.xml。1.2 版本匹配JDK版本決定Maven版本上限我見(jiàn)過(guò)不少人是隨便下一個(gè)Maven版本報(bào)錯(cuò)了才開(kāi)始懷疑環(huán)境。這里有個(gè)很基礎(chǔ)的匹配關(guān)系Maven本身是用Java寫(xiě)的運(yùn)行Maven需要本機(jī)裝有JDK而且不同Maven版本對(duì)JDK版本的要求不同。目前比較常用的Maven 3.6.x要求JDK 1.7以上Maven 3.8.x和3.9.x要求JDK 8以上。如果你用的是Maven 3.9系列JDK 8、11、17、21一般都沒(méi)問(wèn)題但如果你本機(jī)只裝了JDK 1.6或更老那就只能找老版本的Maven這不現(xiàn)實(shí)建議直接升級(jí)JDK。具體選哪個(gè)版本我會(huì)建議選最新的Maven 3.9.x穩(wěn)定版。原因有兩個(gè)一是和現(xiàn)代JDK的兼容性更好二是3.x系列在Windows下的使用經(jīng)驗(yàn)最豐富遇到問(wèn)題容易搜到解決方案。別去嘗鮮Maven 4.x除非你想當(dāng)小白鼠。1.3 確認(rèn)JAVA_HOME指向JDK而不是JRE這是Windows下最常見(jiàn)、也最隱蔽的一個(gè)坑。很多Windows系統(tǒng)的機(jī)器在安裝JDK后其實(shí)還帶著一個(gè)單獨(dú)的JRE。如果你在環(huán)境變量里把JAVA_HOME配到了JRE目錄Maven啟動(dòng)時(shí)會(huì)直接提示找不到編譯器環(huán)境或者干脆報(bào)出奇怪錯(cuò)誤。檢查方法很簡(jiǎn)單在命令行執(zhí)行echo %JAVA_HOME%正常情況下應(yīng)該指向類似C:\Program Files\Java\jdk-17這樣的路徑而不是C:\Program Files\Java\jre17??梢杂孟旅孢@張表快速核對(duì)檢查項(xiàng)命令期望結(jié)果Java版本java -version輸出中包含jdk版本信息JAVA_HOME路徑echo %JAVA_HOME%指向JDK安裝目錄而非JRE目錄編譯命令javac -version能正常輸出版本號(hào)如果javac命令提示找不到說(shuō)明Path里沒(méi)有JDK的bin目錄這在后面配置環(huán)境變量時(shí)會(huì)一并解決。2. 下載解壓與目錄結(jié)構(gòu)裝到C盤(pán)外后面會(huì)省很多事2.1 下載時(shí)別選錯(cuò)包bin.zip與src.zip去Maven官網(wǎng)的下載頁(yè)面會(huì)看到一連串文件。需要選擇的是apache-maven-3.9.x-bin.zip這才是可直接運(yùn)行的二進(jìn)制發(fā)行包。旁邊那些-src.zip是源碼包下載下來(lái)沒(méi)法直接運(yùn)行。Windows用戶不要點(diǎn)tar.gz那是給Linux和macOS準(zhǔn)備的Windows下解壓不是不行但沒(méi)必要。下載完成后得到一個(gè)zip壓縮包解壓即可不需要安裝程序。Maven本身是綠色軟件這點(diǎn)和Linux上的使用習(xí)慣很像。2.2 解壓后目錄結(jié)構(gòu)速覽解壓后你會(huì)看到一個(gè)以版本號(hào)命名的文件夾比如apache-maven-3.9.6。打開(kāi)里面是這樣的apache-maven-3.9.6/ ├── bin/ # mvn可執(zhí)行腳本 ├── conf/ # 核心配置文件settings.xml ├── lib/ # Maven運(yùn)行所需的jar包 └── boot/ # Maven自身啟動(dòng)的類加載器初學(xué)者最容易忽略的是conf/settings.xml和bin/mvn.cmd。前者是全局配置文件本地倉(cāng)庫(kù)位置、鏡像源、代理信息都在這里改后者是Windows下的啟動(dòng)腳本環(huán)境變量驗(yàn)證時(shí)看的就是它。2.3 目錄路徑的兩個(gè)忌諱解壓位置看起來(lái)無(wú)所謂但實(shí)際在Windows下有兩個(gè)忌諱第一路徑不要帶中文和空格。比如D:\軟件\maven這種路徑在某些舊版工具鏈里會(huì)出現(xiàn)編碼或路徑解析問(wèn)題。建議放在D:\tools\apache-maven-3.9.6這樣的純英文路徑下。第二盡量不要裝到C盤(pán)系統(tǒng)盤(pán)。Maven的本地倉(cāng)庫(kù)默認(rèn)是在用戶目錄下的.m2文件夾一旦項(xiàng)目多了依賴包體積會(huì)迅速膨脹。C盤(pán)空間緊張會(huì)拖累系統(tǒng)。如果你把Maven本身也放在C盤(pán)后面想挪會(huì)很麻煩。3. 環(huán)境變量設(shè)置與驗(yàn)證這一步翻車概率最高3.1 從新建MAVEN_HOME到修改Path解壓完并不代表裝好了還差最關(guān)鍵的一步環(huán)境變量。Windows下配置Maven環(huán)境變量需要兩個(gè)動(dòng)作。右鍵“此電腦” - 屬性 - 高級(jí)系統(tǒng)設(shè)置 - 環(huán)境變量在“系統(tǒng)變量”區(qū)域點(diǎn)擊“新建”變量名填MAVEN_HOME變量值填Maven的解壓路徑。比如MAVEN_HOME D:\tools\apache-maven-3.9.6然后在已有的Path變量里追加一條%MAVEN_HOME%\bin為什么要專門(mén)建一個(gè)MAVEN_HOME再引用而不是直接寫(xiě)完整路徑一是之后升級(jí)Maven版本時(shí)只需要改MAVEN_HOME這一個(gè)地方二是很多工程化工具會(huì)自動(dòng)讀取MAVEN_HOME環(huán)境變量提前配好能省不少事。3.2 命令行驗(yàn)證mvn -v 輸出應(yīng)該長(zhǎng)什么樣配置完成后重新打開(kāi)一個(gè)命令行窗口注意舊窗口可能不會(huì)刷新環(huán)境變量執(zhí)行mvn -v正常情況下會(huì)輸出一段信息。重點(diǎn)看兩行Apache Maven 3.9.6 (... Maven home: D:\tools\apache-maven-3.9.6 Java version: 17.0.10, vendor: ... Java home: C:\Program Files\Java\jdk-17Maven home對(duì)Java home對(duì)說(shuō)明環(huán)境變量配置成功。如果輸出的是“不是內(nèi)部或外部命令”大概率是Path沒(méi)配置好或者命令行窗口沒(méi)重開(kāi)。3.3 驗(yàn)證失敗的常見(jiàn)原因排查現(xiàn)象可能原因處理方式mvn 不是內(nèi)部或外部命令Path中未包含%MAVEN_HOME%\bin重新檢查PathMaven啟動(dòng)報(bào)錯(cuò)JAVA_HOME變量不存在或指向錯(cuò)誤確認(rèn)JAVA_HOME指向JDK輸出亂碼控制臺(tái)編碼問(wèn)題后續(xù)統(tǒng)一處理Java version顯示的是舊版本JDK版本沖突檢查Path中是否有多余的Java路徑我在實(shí)際中遇到過(guò)一種很隱蔽的情況機(jī)器上裝了多個(gè)JDKPath里既有JDK 8的路徑又有JDK 17的路徑導(dǎo)致Maven啟動(dòng)時(shí)用了錯(cuò)誤版本。解決辦法是在Path里把希望使用的JDK bin目錄排到前面或者干脆把多余的JDK環(huán)境變量清理干凈。4. settings.xml才是安裝的重頭戲本地倉(cāng)庫(kù)和鏡像配置4.1 先搞清楚settings.xml什么時(shí)候生效裝好Maven后大多數(shù)人直接就打開(kāi)項(xiàng)目開(kāi)始下載依賴。這時(shí)候如果發(fā)現(xiàn)下載特別慢或者依賴很難拉全問(wèn)題基本都出在Maven的配置文件上。Maven有兩個(gè)層級(jí)的settings.xml全局配置文件在%MAVEN_HOME%\conf\settings.xml用戶級(jí)配置文件在C:\Users\用戶名\.m2\settings.xml。如果兩個(gè)都存在用戶級(jí)的會(huì)覆蓋全局配置。實(shí)際使用中我更建議直接改全局配置文件因?yàn)橛脩艏?jí)的文件不會(huì)自動(dòng)創(chuàng)建很多初學(xué)者根本不知道它的存在。4.2 修改localRepository把依賴倉(cāng)庫(kù)挪出C盤(pán)打開(kāi)conf目錄下的settings.xml找到下面這段默認(rèn)注釋內(nèi)容localRepository${user.home}/.m2/repository/localRepository默認(rèn)情況下所有下載下來(lái)的依賴jar包都會(huì)存到用戶目錄的.m2/repository文件夾里。這有兩個(gè)問(wèn)題一是C盤(pán)空間壓力大二是一旦系統(tǒng)重裝這些依賴全沒(méi)。我的做法是把它改成D盤(pán)的一個(gè)固定目錄localRepositoryD:\maven-repo/localRepository改完后本地倉(cāng)庫(kù)就統(tǒng)一放到D盤(pán)。以后重裝系統(tǒng)、換Maven版本只要路徑不變依賴包還能繼續(xù)使用省去重新下載的麻煩。注意改完這個(gè)路徑后第一次執(zhí)行Maven命令會(huì)自動(dòng)創(chuàng)建該目錄不需要手動(dòng)創(chuàng)建。4.3 鏡像源配置解決國(guó)內(nèi)下載慢的問(wèn)題Maven默認(rèn)從中央倉(cāng)庫(kù)下載依賴這個(gè)倉(cāng)庫(kù)服務(wù)器在國(guó)外國(guó)內(nèi)訪問(wèn)經(jīng)常很慢或者直接卡住。解決思路很直接配置一個(gè)國(guó)內(nèi)公共倉(cāng)庫(kù)鏡像。在settings.xml的mirrors標(biāo)簽內(nèi)添加一個(gè)mirror節(jié)點(diǎn)。這里以國(guó)內(nèi)常用的公共倉(cāng)庫(kù)地址為例mirror idpublic-mirror/id mirrorOfcentral/mirrorOf namePublic Mirror/name urlhttps://maven.aliyun.com/repository/public/url /mirror這里的關(guān)鍵是mirrorOfcentral/mirrorOf表示所有對(duì)中央倉(cāng)庫(kù)的請(qǐng)求都走這個(gè)鏡像。實(shí)際使用中這個(gè)地址的下載速度和穩(wěn)定性比默認(rèn)倉(cāng)庫(kù)可靠得多。類似的公共鏡像還有幾個(gè)比如騰訊云、華為云的Maven倉(cāng)庫(kù)配置方式完全一樣只需要換一下url。如果某個(gè)鏡像不穩(wěn)定換一個(gè)就行。4.4 鏡像配置的兩個(gè)小細(xì)節(jié)不少人在這一步栽過(guò)跟頭。配置鏡像后下載速度確實(shí)快了但有些項(xiàng)目里有特殊依賴來(lái)自某個(gè)私有倉(cāng)庫(kù)。如果mirrorOf寫(xiě)的是*那所有倉(cāng)庫(kù)的請(qǐng)求都會(huì)被鏡像劫持私有倉(cāng)庫(kù)里的依賴反而拉不下來(lái)了。我的習(xí)慣是鏡像只覆蓋中央倉(cāng)庫(kù)即mirrorOf寫(xiě)成central。如果項(xiàng)目里確實(shí)需要額外倉(cāng)庫(kù)再單獨(dú)在pom.xml里配置倉(cāng)庫(kù)地址這樣各司其職。另一個(gè)細(xì)節(jié)是修改settings.xml后需要重啟IDE才會(huì)生效否則IDE里用的還是舊配置。5. 跑通第一個(gè)構(gòu)建核心命令與一個(gè)能用的pom.xml5.1 最小pom.xml長(zhǎng)這樣環(huán)境配好、鏡像配好之后該實(shí)際跑一個(gè)項(xiàng)目了。不管你現(xiàn)在用的IDE是什么第一步都可以先建一個(gè)純命令行的Maven項(xiàng)目來(lái)驗(yàn)證整條鏈路。在任意目錄下新建一個(gè)pom.xml文件內(nèi)容可以非常精簡(jiǎn)project 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/maven-4.0.0.xsd modelVersion4.0.0/modelVersion groupIdcom.example/groupId artifactIddemo-maven/artifactId version1.0-SNAPSHOT/version packagingjar/packaging properties maven.compiler.source17/maven.compiler.source maven.compiler.target17/maven.compiler.target project.build.sourceEncodingUTF-8/project.build.sourceEncoding /properties /projectgroupId、artifactId、version這三個(gè)坐標(biāo)共同決定了一個(gè)Maven項(xiàng)目的身份。source和target兩個(gè)屬性分別表示源碼的Java版本和編譯后class文件的版本如果你的JDK是11就寫(xiě)11是8就寫(xiě)8別直接照抄17。5.2 從clean到install完整命令順序在pom.xml所在目錄打開(kāi)命令行按順序執(zhí)行下面幾條命令mvn clean compile mvn test mvn package mvn install這里簡(jiǎn)單說(shuō)明每一條的作用。mvn clean是清理target目錄把之前的編譯產(chǎn)物刪掉避免殘留文件影響新的構(gòu)建。mvn compile編譯主代碼到target/classes。mvn test執(zhí)行src/test/java下的單元測(cè)試。mvn package把項(xiàng)目按照pom.xml中packaging指定的方式打包成jar或war文件生成在target目錄下。mvn install會(huì)把打包產(chǎn)物安裝到本地倉(cāng)庫(kù)。這部分很多初學(xué)者不理解為什么要install因?yàn)橥粋€(gè)機(jī)器上有多個(gè)項(xiàng)目互相依賴時(shí)A項(xiàng)目想用B項(xiàng)目的jar包B項(xiàng)目必須先install到本地倉(cāng)庫(kù)A項(xiàng)目才能以依賴方式引用。5.3 三個(gè)特別容易混的命令命令作用影響范圍package打包但不安裝只生成target下的產(chǎn)物install打包并安裝到本地倉(cāng)庫(kù)本機(jī)其他項(xiàng)目可用deploy打包并上傳到遠(yuǎn)程倉(cāng)庫(kù)團(tuán)隊(duì)協(xié)作時(shí)使用實(shí)際開(kāi)發(fā)中clean經(jīng)常和后面命令連用最常見(jiàn)的是mvn clean install。我看到很多人只執(zhí)行package然后在別的項(xiàng)目里引用時(shí)發(fā)現(xiàn)找不到依賴就是沒(méi)搞清楚install和package的區(qū)別。5.4 IDE里配置Maven用自己裝的別用自帶的如果你用的是常見(jiàn)Java IDE比如IDEA打開(kāi)項(xiàng)目后IDE默認(rèn)會(huì)使用它自帶的Maven。這個(gè)自帶版本通常沒(méi)問(wèn)題但會(huì)有兩個(gè)隱患一是自帶Maven的settings.xml可能不是你自己配置的鏡像下載依然慢二是升級(jí)IDE后Maven行為可能變化。建議手動(dòng)把IDE里的Maven指向自己安裝的版本。以IDEA為例進(jìn)入 Settings - Build, Execution, Deployment - Build Tools - Maven依次設(shè)置Maven home path選到你的Maven解壓目錄User settings file勾選Override并選擇你的settings.xml路徑Local repository如果配置的是D:\maven-repo這里會(huì)自動(dòng)讀取設(shè)置完重啟項(xiàng)目讓IDE重新導(dǎo)入Maven配置。第一次導(dǎo)入會(huì)下載很多依賴只要鏡像配好了速度一般很快。6. 實(shí)戰(zhàn)中遇到的高頻問(wèn)題與排查鏈路6.1 中文亂碼從環(huán)境變量到IDE的一整套解法Maven構(gòu)建日志里如果中文變成一堆問(wèn)號(hào)或亂碼通常不是代碼問(wèn)題而是默認(rèn)編碼不一致。先檢查pom.xml里是否設(shè)置了project.build.sourceEncodingUTF-8/project.build.sourceEncoding如果設(shè)置了還是亂碼再看命令行窗口的代碼頁(yè)。在Windows的cmd里執(zhí)行chcp 65001切換到UTF-8編碼。如果是IDE的控制臺(tái)在IDE的啟動(dòng)參數(shù)里加一行-Dfile.encodingUTF-8然后重啟IDE。通常這一套操作下來(lái)亂碼問(wèn)題基本能解決。6.2 依賴下載失敗或卡住.lastUpdated文件是什么鏡像配好了但偶爾還是會(huì)遇到某個(gè)依賴下載失敗之后再執(zhí)行命令就一直卡在同一個(gè)jar包。此時(shí)本地倉(cāng)庫(kù)對(duì)應(yīng)目錄下會(huì)出現(xiàn).lastUpdated后綴的文件這是Maven記錄下載失敗狀態(tài)的標(biāo)記文件。只要這個(gè)文件存在Maven就不會(huì)重新嘗試下載。清除方式很簡(jiǎn)單在命令行執(zhí)行mvn -U clean compile其中-U參數(shù)強(qiáng)制檢查遠(yuǎn)程倉(cāng)庫(kù)更新。更徹底的做法是手動(dòng)刪除本地倉(cāng)庫(kù)中對(duì)應(yīng)目錄下的lastUpdated文件再重新構(gòu)建。我在項(xiàng)目里遇到過(guò)這種場(chǎng)景明明換了鏡像源某個(gè)快照版本依賴還是反復(fù)失敗后來(lái)發(fā)現(xiàn)是本地倉(cāng)庫(kù)里的失敗記錄沒(méi)清理。6.3 依賴沖突用dependency:tree看依賴樹(shù)項(xiàng)目稍微變大就可能出現(xiàn)兩個(gè)依賴傳遞引入了同一個(gè)庫(kù)的不同版本?,F(xiàn)象很典型編譯正常運(yùn)行時(shí)報(bào)NoSuchMethodError或ClassNotFoundException。排查思路很簡(jiǎn)單執(zhí)行mvn dependency:treeMaven會(huì)把整個(gè)依賴樹(shù)打印出來(lái)你很快能看到同一個(gè)groupId出現(xiàn)了多個(gè)版本。處理方式是在pom.xml中顯式聲明需要用到的版本或者對(duì)某個(gè)傳遞依賴做排除。dependency groupIdorg.example/groupId artifactIddemo-lib/artifactId version1.0.0/version exclusions exclusion groupIdorg.example/groupId artifactIdconflict-lib/artifactId /exclusion /exclusions /dependency6.4 新電腦裝Maven的個(gè)人習(xí)慣最后分享一點(diǎn)我自己的習(xí)慣。每次在一臺(tái)新Windows電腦上裝Maven我不會(huì)先急著執(zhí)行IDE里的項(xiàng)目而是先按下面這個(gè)順序走一遍第一用java -version和javac -version確認(rèn)JDK可用再執(zhí)行mvn -v看Maven是否識(shí)別到正確的Java環(huán)境。第二把settings.xml里的本地倉(cāng)庫(kù)路徑和鏡像源先改好然后執(zhí)行一個(gè)最簡(jiǎn)單的mvn help:system命令讓Maven自動(dòng)初始化本地倉(cāng)庫(kù)并讀取配置。第三跑一個(gè)最簡(jiǎn)單的pom.xml項(xiàng)目把clean、compile、package整條鏈路走通再打開(kāi)IDE導(dǎo)入項(xiàng)目。這套流程每次都能幫我提前發(fā)現(xiàn)環(huán)境問(wèn)題而不是等IDE里項(xiàng)目導(dǎo)入失敗后才開(kāi)始排查。如果你是第一次在Windows下配置Maven建議也按這個(gè)順序來(lái)能少走很多彎路。