
簡介openjdk-8u292-b10-windows-x64.zip 是一份面向 Windows x64 平臺(tái)的 Java 8JDK 1.8開發(fā)環(huán)境壓縮包主要服務(wù)于需要配置 Java 運(yùn)行或開發(fā)環(huán)境的個(gè)人開發(fā)者與企業(yè)團(tuán)隊(duì)可幫助解決多版本 JDK 共存、環(huán)境遷移以及舊項(xiàng)目升級(jí)等問題。壓縮包整體約 109.15MB除安裝程序外還包括 JDK 核心類庫、JRE 運(yùn)行時(shí)和常用命令行工具結(jié)構(gòu)清晰便于快速部署用戶可根據(jù)需要選擇僅安裝 JRE 或完整 JDK靈活性較高。此版本在 JVM 的垃圾回收與分層編譯方面做了優(yōu)化同時(shí)引入 Lambda 表達(dá)式、Stream API、Optional 容器、全新日期時(shí)間 API、接口默認(rèn)方法、Nashorn JavaScript 引擎以及 Fork/Join 并發(fā)框架能夠幫助開發(fā)者以更簡潔的方式處理集合、異步任務(wù)和并行計(jì)算降低空指針異常風(fēng)險(xiǎn)提高代碼質(zhì)量與運(yùn)行效率也讓日常維護(hù)變得更加便捷。目前已有 511 人學(xué)習(xí)下載適合作為日常開發(fā)、環(huán)境升級(jí)或技術(shù)學(xué)習(xí)的可靠選擇。1. 為什么一個(gè) openjdk-8u292-b10-windows-x64.zip 還在被到處下載如果你手里有一個(gè)openjdk-8u292-b10-windows-x64.zip大概率不是沖著新特性來的而是要給某個(gè)老項(xiàng)目、某臺(tái)離線測試機(jī)配一個(gè)干凈的 Java 8 運(yùn)行時(shí)。這個(gè)文件名背后是一套非常經(jīng)典的組合OpenJDK 8 的第 292 個(gè) update、Windows 64 位平臺(tái)、zip 分發(fā)包而不是安裝器。很多公司的后端生產(chǎn)環(huán)境到現(xiàn)在還把 Java 鎖在這一代小版本上因?yàn)樯?jí)帶來的不是新功能而是類加載行為變化、加密策略調(diào)整、第三方依賴不兼容之類的風(fēng)險(xiǎn)。這個(gè) zip 包能解決的核心問題很具體解壓即用、不寫注冊(cè)表、不裝后臺(tái)更新給“我需要一個(gè)可控的 JDK”提供了最樸素也最穩(wěn)的方案。這篇筆記適合接手遺留系統(tǒng)的后端開發(fā)、要給測試機(jī)快速裝環(huán)境的同學(xué)以及在內(nèi)網(wǎng)做批量部署的運(yùn)維。2. 看懂 openjdk-8u292-b10-windows-x64.zip版本號(hào)、zip 與安裝器的差別、裝前規(guī)劃2.1 版本號(hào)拆解8u292 和 b10 分別決定了什么外行看這串版本號(hào)容易懵OpenJDK 8 的版本規(guī)則其實(shí)很固定。8u292里的 292 是 Java SE 8 的 update 編號(hào)代表安全補(bǔ)丁和 bug 修復(fù)的累計(jì)水平數(shù)字越大補(bǔ)丁越新b10則是這次 update 的第 10 個(gè)構(gòu)建產(chǎn)物用于區(qū)分同一批 update 內(nèi)部的不同構(gòu)建也在下載站上用于唯一標(biāo)識(shí)同一個(gè)文件。對(duì)使用者來說只需要記住一條判斷標(biāo)準(zhǔn)update 數(shù)字決定補(bǔ)丁新舊build 數(shù)字決定你拿到的到底是不是同一個(gè)二進(jìn)制。兩個(gè)不同網(wǎng)站提供的 8u292build 號(hào)一樣通??梢哉J(rèn)為構(gòu)建來源一致。為什么 8u292 在很多公司成了事實(shí)標(biāo)準(zhǔn)Java 8 是典型的 LTS 版本這里 LTS 的意義不是“永久免費(fèi)”而是維護(hù)周期被拉得很長。幾年前 Java 8 的公開免費(fèi)更新策略調(diào)整后大量團(tuán)隊(duì)不再無腦追新而是把版本鎖在一個(gè)已知穩(wěn)定、補(bǔ)丁足夠晚、社區(qū)踩坑記錄足夠多的 update 上。8u292 恰好落在“還能方便獲取、補(bǔ)丁時(shí)間較晚、被大量中間件驗(yàn)證過”這個(gè)交集里。同一代 Java 8 里不同 update 對(duì)業(yè)務(wù)代碼的 API 影響很小變化主要集中在加密套件、時(shí)區(qū)數(shù)據(jù)、安全策略所以老項(xiàng)目從某個(gè)舊 update 遷到 8u292通常比升級(jí)大版本要從容得多。另外要區(qū)分一下 JDK 和 JRE。這個(gè) zip 解壓出來是完整 JDK目錄里有javac.exe、javap.exe、jarsigner.exe這些開發(fā)工具也有一個(gè)jre子目錄。如果你只是部署一個(gè)跑服務(wù)的 Java 程序理論上只用 JRE 就夠但新裝機(jī)器我建議直接上完整 JDK因?yàn)楹竺媾挪?class 版本、看反編譯、做簽名都要用 JDK 里的工具缺了再補(bǔ)很麻煩。2.2 zip 分發(fā)包和安裝器為什么我堅(jiān)持用 zipWindows 上裝 Java 有兩條路線下載 zip 解壓或者下載安裝器一路下一步。安裝器的確省事但它在系統(tǒng)里做的事比你想象得多。它會(huì)把一個(gè)轉(zhuǎn)發(fā)用的 java.exe 放到系統(tǒng)公共 Java 目錄會(huì)注冊(cè)更新計(jì)劃任務(wù)還會(huì)把自身版本信息寫進(jìn)注冊(cè)表。這些東西單看每一項(xiàng)都不致命合在一起就成了環(huán)境問題的溫床——最常見的現(xiàn)象是你明明裝了新 JDK打開命令行卻還是舊版本因?yàn)橄到y(tǒng)公共目錄里那個(gè) java.exe 的優(yōu)先級(jí)比你配的 PATH 更靠前。zip 包和安裝器的差異用一張表能看得很清楚對(duì)比項(xiàng)zip 分發(fā)包安裝器注冊(cè)表寫入無寫入版本信息和公共 Java 路徑管理員權(quán)限不需要需要多版本共存隨意目錄隔離容易互相覆蓋轉(zhuǎn)發(fā)器卸載刪目錄即完成需要走卸載程序批量部署復(fù)制目錄即可需要靜默參數(shù)或組策略我的選擇原則很固定凡是做開發(fā)和運(yùn)維、需要精確控制 JDK 版本的機(jī)器一律用 zip 解壓到固定目錄只有給不懂技術(shù)的終端用戶分發(fā)桌面應(yīng)用時(shí)才考慮安裝器。原因很簡單zip 包給了你完整的控制權(quán)安裝器把一部分控制權(quán)交給了系統(tǒng)。對(duì)于“環(huán)境必須可復(fù)現(xiàn)”這個(gè)要求來說控制權(quán)比省那十分鐘更重要。2.3 裝前必須定的三件事目錄、校驗(yàn)、命名第一件事是目標(biāo)目錄。別把 JDK 解壓到C:\Program Files這類帶空格的路徑原因有兩個(gè)一是批處理腳本里調(diào)用%JAVA_HOME%\bin\java.exe時(shí)空格會(huì)拆散路徑得靠引號(hào)兜底二是這個(gè)目錄默認(rèn)受系統(tǒng)權(quán)限保護(hù)后續(xù)改文件、加擴(kuò)展容易遇到權(quán)限攔截。我一般用D:\jdk\jdk8u292盤符和根路徑按團(tuán)隊(duì)規(guī)約定但無論如何要保證整條路徑?jīng)]有空格。第二件事是校驗(yàn)壓縮包完整性。zip 在傳輸過程中損壞是高頻事故解壓到一半報(bào) CRC 錯(cuò)誤才反應(yīng)過來就浪費(fèi)時(shí)間了。OpenJDK 發(fā)布頁會(huì)給每個(gè)文件提供 SHA256 摘要下載完先算一遍再解壓Get-FileHash -Algorithm SHA256 D:\downloads\openjdk-8u292-b10-windows-x64.zip算出來的哈希值和發(fā)布頁給的比對(duì)一致再繼續(xù)。Get-FileHash是 PowerShell 自帶的命令-Algorithm指定算法不傳默認(rèn)就是 SHA256。這一步看起來多余但在離線內(nèi)網(wǎng)環(huán)境、用 U 盤拷貝的場景里它能省下一個(gè)小時(shí)的排錯(cuò)時(shí)間。第三件事是命名規(guī)范。解壓后的頂層目錄名通常是jdk8u292-b10這種帶 build 后綴的名字我會(huì)直接重命名為jdk8u292不帶平臺(tái)和 build。好處是后面寫腳本、配環(huán)境變量時(shí)路徑固定以后升級(jí)到 8u312 就換一個(gè)目錄名所有腳本只改一行。目錄名里保留平臺(tái)信息反而是冗余因?yàn)槟阋呀?jīng)把包放在D:\jdk下了看鄰居目錄就知道這機(jī)器上有哪些平臺(tái)。3. 安裝與配置三步走解壓、環(huán)境變量、驗(yàn)證3.1 用 PowerShell 解壓并固定目錄名解壓這件事在 Windows 上有很多姿勢(shì)但論可腳本化、可重復(fù)執(zhí)行PowerShell 的Expand-Archive是最穩(wěn)的。下面這段我一般直接保存成install-jdk8.ps1換臺(tái)機(jī)器改個(gè)變量就能跑$zip D:\downloads\openjdk-8u292-b10-windows-x64.zip $dest D:\jdk # 解壓到目標(biāo)目錄存在內(nèi)容時(shí)強(qiáng)制覆蓋 Expand-Archive -Path $zip -DestinationPath $dest -Force # 找到解壓出來的頂層目錄統(tǒng)一改名為 jdk8u292 $folder Get-ChildItem -Path $dest -Directory | Where-Object { $_.Name -like *8u292* } | Select-Object -First 1 if ($folder -and -not (Test-Path $dest\jdk8u292)) { Rename-Item -Path $folder.FullName -NewName jdk8u292 } # 確認(rèn)關(guān)鍵文件存在 Test-Path $dest\jdk8u292\bin\java.exeExpand-Archive的-DestinationPath指定解壓根目錄-Force表示目標(biāo)目錄下已有同名內(nèi)容時(shí)直接覆蓋。Get-ChildItem配合-Directory只取目錄-like *8u292*做模糊匹配避免你目錄里還有其他版本時(shí)選錯(cuò)。Test-Path最后返回True說明解壓成功。注意Rename-Item只在jdk8u292不存在時(shí)執(zhí)行重復(fù)跑這個(gè)腳本不會(huì)報(bào)錯(cuò)。如果你的下載對(duì)象不是 zip 而是 tar.gzExpand-Archive就吃不消了Windows 10 1803 之后的系統(tǒng)自帶tar命令可以用tar -xf openjdk-8u292-b10-windows-x64.tar.gz -C D:\jdk解壓-C指定輸出目錄效果一樣。3.2 環(huán)境變量JAVA_HOME、PATH、JAVA_TOOL_OPTIONS 各管什么環(huán)境變量配置是裝 JDK 里最容易被講糊的一步。其實(shí) Windows 上 Java 相關(guān)變量只有三個(gè)需要關(guān)心職責(zé)分得很清變量作用示例值注意JAVA_HOME給 Java 工具和腳本定位 JDK 根目錄D:\jdk\jdk8u292不能帶 bin 后綴PATH讓命令行直接找到 java.exe、javac.exe%JAVA_HOME%\bin;...追加順序決定優(yōu)先級(jí)JAVA_TOOL_OPTIONS給所有 JVM 進(jìn)程預(yù)置參數(shù)默認(rèn)不設(shè)置設(shè)置后會(huì)全局生效JAVA_HOME的值必須寫到bin的上一級(jí)也就是 JDK 根目錄。PATH里要追加的是%JAVA_HOME%\bin這樣系統(tǒng)才能順著變量找到可執(zhí)行文件。JAVA_TOOL_OPTIONS是最容易誤用的一個(gè)它的本意是給那些不方便改啟動(dòng)命令的場景注入 JVM 參數(shù)但副作用是所有 Java 進(jìn)程都會(huì)讀到它啟動(dòng)時(shí)還會(huì)在控制臺(tái)打一行Picked up JAVA_TOOL_OPTIONS我建議默認(rèn)不設(shè)置。設(shè)置方式有圖形界面和setx命令兩種。setx看著高效實(shí)則有兩個(gè)著名的坑一是它會(huì)把當(dāng)前的PATH整個(gè)讀入命令行再寫回一旦PATH太長就有截?cái)囡L(fēng)險(xiǎn)把已有路徑弄丟是網(wǎng)上常見的“后悔藥”現(xiàn)場二是它只寫入注冊(cè)表不會(huì)刷新當(dāng)前已打開的窗口配完必須在新的命令行里驗(yàn)證。我一般優(yōu)先用圖形界面系統(tǒng)屬性 → 環(huán)境變量 → 新建JAVA_HOME→ 編輯PATH追加%JAVA_HOME%\bin。GUI 能讓你看清楚當(dāng)前PATH的全貌不被截?cái)鄦栴}偷襲。如果你是趕時(shí)間堅(jiān)持用setx至少這樣做setx JAVA_HOME D:\jdk\jdk8u292 setx PATH %PATH%;%JAVA_HOME%\bin注意這兩條命令都會(huì)立即覆蓋注冊(cè)表里的對(duì)應(yīng)值而且不通知任何已開著的程序。配完之后不要在當(dāng)前窗口驗(yàn)證新開一個(gè) cmd 再跑。還有一點(diǎn)要分清用戶變量只對(duì)當(dāng)前用戶生效系統(tǒng)變量對(duì)整臺(tái)機(jī)器和 Windows 服務(wù)生效。如果你的 Java 程序要跑在服務(wù)里只配用戶變量是沒用的服務(wù)進(jìn)程讀不到。3.3 驗(yàn)證java -version 應(yīng)該輸出什么配置完成后新開一個(gè) cmd 窗口按順序執(zhí)行三條命令echo %JAVA_HOME% where java java -versionecho %JAVA_HOME%先確認(rèn)變量值沒被引號(hào)或反斜杠污染where java列出 PATH 里所有命中的 java.exe 以及命中順序這是排查環(huán)境問題最重要的命令java -version看實(shí)際生效的版本。正常情況下的輸出長這樣openjdk version 1.8.0_292 OpenJDK Runtime Environment (build 1.8.0_292-b10) OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)逐行看第一行是產(chǎn)品版本1.8.0_292就是 8u292 的內(nèi)部寫法第二行是運(yùn)行時(shí)環(huán)境的構(gòu)建標(biāo)識(shí)第三行最關(guān)鍵64-Bit Server VM說明你拿到的確實(shí)是 x64 平臺(tái)的 HotSpot 虛擬機(jī)mixed mode表示默認(rèn)的混合執(zhí)行模式解釋執(zhí)行和即時(shí)編譯并存。如果第三行沒有64-Bit字樣說明 PATH 里先命中了一個(gè) 32 位 JDK后文會(huì)專門講這個(gè)坑。where java的輸出也應(yīng)該只有一行指向D:\jdk\jdk8u292\bin\java.exe。如果列出來好幾個(gè)路徑說明機(jī)器上還有其他 Java這時(shí)就要按優(yōu)先級(jí)處理 PATH 順序。最后順手驗(yàn)證一下編譯器javac -version輸出javac 1.8.0_292才算完整裝好。4. 項(xiàng)目級(jí)接入讓 IDE 和 mvn 都跑在這個(gè) 8u292 上4.1 在 IDE 里指定 JDK而不是依賴 PATH命令行配好環(huán)境變量只是第一步開發(fā)工具里的 Java 路徑是另一套邏輯。大多數(shù) IDE 在首次啟動(dòng)時(shí)會(huì)自動(dòng)探測系統(tǒng)里的 JDK但探測順序不保證是你剛裝的這個(gè)。如果你在 IDE 里 Build 項(xiàng)目時(shí)用的是它自己選中的舊 JDK命令行再怎么配也影響不到 IDE 內(nèi)的編譯結(jié)果這是很多“我明明配好了 8u292怎么 IDE 里還是報(bào)錯(cuò)”的根源。常見做法是在 IDE 的項(xiàng)目結(jié)構(gòu)設(shè)置里找到 SDK 或 Platform 配置手動(dòng)添加 JDK把路徑指到D:\jdk\jdk8u292根目錄不要指到bin目錄。IDE 會(huì)掃描這個(gè)目錄下的bin\javac.exe和bin\java.exe自動(dòng)識(shí)別出這是 Java 8。項(xiàng)目級(jí)別的 language level 也同步選成 8這樣代碼提示和編譯行為都對(duì)齊 8u292。這里要說一個(gè)容易繞暈的點(diǎn)IDE 自己是用哪個(gè) JDK 啟動(dòng)的和項(xiàng)目用哪個(gè) JDK 編譯是兩碼事。IDE 程序本身可以跑在新的 JDK 上完全不影響項(xiàng)目編譯反過來項(xiàng)目 SDK 指對(duì)了IDE 啟動(dòng)用的 JDK 不對(duì)也不會(huì)影響構(gòu)建。所以遇到“IDE 里編譯報(bào) invalid source release: 8”先檢查 Project SDK 是否指向 8u292再看 language level最后看模塊設(shè)置里有沒有覆蓋全局配置三層都對(duì)了基本就能消停。4.2 用 mvn -version 確認(rèn)構(gòu)建工具吃到了哪個(gè) JDK構(gòu)建工具比 IDE 更直接它繼承的就是終端里的環(huán)境變量。很多人在 cmd 里配好了路徑但用 IDE 內(nèi)嵌終端跑構(gòu)建時(shí)又拿不到同一個(gè)變量。以 mvn 構(gòu)建工具為例第一步永遠(yuǎn)是先問它自己用的是哪個(gè) Javaset JAVA_HOMED:\jdk\jdk8u292 set PATH%JAVA_HOME%\bin;%PATH% mvn -version這段先把當(dāng)前進(jìn)程的JAVA_HOME指到 8u292再把它的bin插到 PATH 最前面然后啟動(dòng) mvn。mvn -version輸出的Java version字段如果顯示1.8.0_292說明構(gòu)建進(jìn)程確實(shí)跑在 8u292 上。注意這里用的是set而不是setxset只修改當(dāng)前 cmd 進(jìn)程的變量關(guān)掉窗口就失效這是刻意為之按項(xiàng)目或按窗口隔離而不是全局污染。項(xiàng)目里的構(gòu)建配置也要寫死語言級(jí)別properties maven.compiler.source1.8/maven.compiler.source maven.compiler.target1.8/maven.compiler.target /properties這兩個(gè)參數(shù)告訴 javac 生成什么語言級(jí)別的字節(jié)碼。但要記住一個(gè)邊界source和target只約束語言特性不約束 API 引用。JDK 9 以后的編譯器加了-release參數(shù)能同時(shí)限制語言級(jí)別和 API 列表而 8u292 自帶的 javac 沒有這個(gè)選項(xiàng)。所以在 JDK 8 上編譯老項(xiàng)目最可靠的方案就是讓編譯進(jìn)程本身跑在 8u292 上而不是拿一個(gè)新版 JDK 去交叉編譯。如果你的構(gòu)建機(jī)裝的是新版 JDK 卻要產(chǎn)出 Java 8 的產(chǎn)物光配 source/target 不夠這類問題在接手舊平臺(tái)的構(gòu)建任務(wù)時(shí)幾乎必踩直接用 8u292 做編譯環(huán)境是最省心的解法。4.3 多版本 JDK 切換寫項(xiàng)目級(jí)啟動(dòng)腳本而不是全局改寫開發(fā)機(jī)上有 Java 8 也有新版 JDK 很常見。遇到這種情況我的習(xí)慣是“切會(huì)話不切全局”給每個(gè)項(xiàng)目配一個(gè)環(huán)境腳本echo off set JAVA_HOMED:\jdk\jdk8u292 set PATH%JAVA_HOME%\bin;%PATH% java -version保存成jdk8.bat和項(xiàng)目放同一個(gè)目錄。要用老項(xiàng)目時(shí)就先跑它然后在這個(gè)窗口里啟動(dòng) IDE 或構(gòu)建命令要切到新版本就再寫一個(gè)jdk17.bat內(nèi)容只改一行JAVA_HOME。命令行窗口里用set設(shè)置的變量只對(duì)當(dāng)前窗口生效這看起來像限制其實(shí)是保護(hù)機(jī)制不會(huì)影響系統(tǒng)里其他程序。不要用setx去全局切換JAVA_HOME來應(yīng)對(duì)多版本需求原因很現(xiàn)實(shí)Windows 服務(wù)、后臺(tái)任務(wù)、IDE 的守護(hù)進(jìn)程都在讀系統(tǒng)變量你切到新版本去編譯老項(xiàng)目可能把正在運(yùn)行的某個(gè)服務(wù)也切過去了到時(shí)候排查問題的時(shí)間遠(yuǎn)超省下的那一分鐘。多版本 Java 的正確姿勢(shì)是目錄隔離、會(huì)話隔離系統(tǒng)變量里永遠(yuǎn)只留一個(gè)最常用的默認(rèn)值。5. 裝完翻車排查8u292 在 Windows x64 上的五個(gè)常見坑這章列的是我自己在 Windows 上裝 JDK 時(shí)反復(fù)見過的五類問題前兩類占比最高后三類屬于“平時(shí)不炸一炸就玄學(xué)”的類型。所有排查步驟的第一條都是先跑where java看實(shí)際命中路徑第二條是echo %JAVA_HOME%看變量值第三條是新開窗口再試一次。大部分問題都在這三步里現(xiàn)形。5.1 版本不對(duì)java -version 顯示的不是 8u292現(xiàn)象JAVA_HOME和PATH都配好了新開命令行java -version出來的卻是舊版本或某個(gè)奇怪實(shí)現(xiàn)。原因PATH 里存在一個(gè)優(yōu)先級(jí)更高的 java.exe。Windows 的 PATH 是從前往后匹配的哪個(gè) java.exe 先被找到就用哪個(gè)環(huán)境變量配了不等于它會(huì)生效順序錯(cuò)了就是白配。解決先where java看所有命中的路徑然后確認(rèn)D:\jdk\jdk8u292\bin是否在 PATH 的最前面。很多第三方軟件會(huì)在安裝時(shí)往 PATH 里塞自己的 Java 目錄刪完之后一定要重開窗口再看因?yàn)橐验_窗口的環(huán)境變量不會(huì)刷新。5.2 提示“java 不是內(nèi)部或外部命令”現(xiàn)象剛配完環(huán)境變量新開窗口執(zhí)行java -version直接報(bào) command not found。原因PATH 里根本沒有%JAVA_HOME%\bin或者JAVA_HOME這個(gè)變量名拼寫錯(cuò)了又或者值里混進(jìn)了多余的引號(hào)和結(jié)尾反斜杠。這一步經(jīng)常栽在setx的引號(hào)處理上路徑里的空格、結(jié)尾的\都會(huì)微妙地改變注冊(cè)表里存下來的值。解決echo %JAVA_HOME%看輸出是不是干凈的D:\jdk\jdk8u292注意不要以反斜杠結(jié)尾再用資源管理器確認(rèn)D:\jdk\jdk8u292\bin\java.exe真實(shí)存在最后檢查 PATH 里確實(shí)追加了%JAVA_HOME%\bin改完務(wù)必新開命令行。如果確認(rèn)變量沒問題還是報(bào)錯(cuò)檢查是不是當(dāng)前 cmd 窗口在配置前就打開了關(guān)掉重開。5.3 腳本找不到 java.exe但手動(dòng)能運(yùn)行現(xiàn)象雙擊某個(gè)批處理提示找不到文件或找不到路徑但同一臺(tái)機(jī)器上手動(dòng)敲java -version完全正常。原因JDK 裝在了帶空格的路徑里比如C:\Program Files\jdk8u292而批處理調(diào)用%JAVA_HOME%\bin\java.exe時(shí)沒有加引號(hào)空格把這一行拆成了多個(gè)參數(shù)系統(tǒng)自然找不到完整路徑。解決最根治的辦法是裝前就把 JDK 放到無空格路徑也就是前面規(guī)劃階段說的D:\jdk\jdk8u292如果機(jī)器上已經(jīng)有老腳本把調(diào)用方式改成%JAVA_HOME%\bin\java.exe帶引號(hào)執(zhí)行。遇到舊腳本沒權(quán)限改的情況這個(gè)坑會(huì)一直反復(fù)所以我才反復(fù)強(qiáng)調(diào)裝前目錄規(guī)劃。5.4 JAVA_TOOL_OPTIONS 被全局配置污染現(xiàn)象啟動(dòng)某個(gè) Java 應(yīng)用時(shí)控制臺(tái)第一行突然多出Picked up JAVA_TOOL_OPTIONS: ...后面還帶著莫名其妙的 JVM 參數(shù)比如一個(gè)不合適的最大堆內(nèi)存導(dǎo)致小機(jī)器起不來。原因有人在系統(tǒng)變量里設(shè)置了JAVA_TOOL_OPTIONS想給所有 Java 進(jìn)程統(tǒng)一加參數(shù)。這個(gè)變量是全屋廣播對(duì)每個(gè) JVM 進(jìn)程生效包括 IDE 后臺(tái)和構(gòu)建工具于是最初的好意變成了環(huán)境毒藥。解決echo %JAVA_TOOL_OPTIONS%看當(dāng)前值是什么如果有值就把它從系統(tǒng)變量里刪掉單個(gè)應(yīng)用需要特殊參數(shù)時(shí)寫進(jìn)應(yīng)用自己的啟動(dòng)腳本不要用全局變量。這個(gè)問題在團(tuán)隊(duì)共用的測試機(jī)上尤其常見屬于典型的“換臺(tái)機(jī)器就行為不一致”的來源。5.5 32 位和 64 位混用現(xiàn)象應(yīng)用運(yùn)行時(shí)報(bào)Cant load IA 32-bit .dll on a AMD 64-bit platform或者java -version第三行沒有64-Bit字樣。原因機(jī)器是 x64 架構(gòu)但 PATH 里命中了一個(gè) 32 位 JRE或者下載時(shí)拿錯(cuò)了 x86 包。標(biāo)題寫的是windows-x64這個(gè)坑最容易出現(xiàn)在機(jī)器里殘留舊 32 位 JRE 的遷移場景。解決看java -version第三行是不是OpenJDK 64-Bit Server VM用where java確認(rèn)實(shí)際路徑是否指向D:\jdk\jdk8u292如果系統(tǒng)里還有其他 Java 目錄把 x64 的路徑挪到 PATH 最前面或者干脆卸載舊版本。這個(gè)問題不解決后面加裝任何本地庫都會(huì)連環(huán)報(bào)錯(cuò)而且報(bào)錯(cuò)信息往往跟真正的根因離得很遠(yuǎn)。6. 驗(yàn)證一條命令看清 8u292 的真實(shí)家底把這個(gè)安裝變成可交接的資產(chǎn)java -version只能證明“有個(gè) java”不能證明它就是你要的那個(gè) 8u292更不能用來對(duì)齊生產(chǎn)基線。我的做法是再補(bǔ)一條命令把運(yùn)行時(shí)真正的家底一次性拉出來java -XshowSettings:properties -version 21 | findstr /i java.home java.version java.vendor os.arch-XshowSettings:properties會(huì)輸出 JVM 當(dāng)前生效的所有系統(tǒng)屬性管道交給findstr過濾關(guān)鍵字段。重點(diǎn)看java.home它顯示當(dāng)前 JVM 實(shí)際加載的目錄如果輸出不是D:\jdk\jdk8u292說明前面排查得還不夠干凈java.vendor告訴我們這個(gè) OpenJDK 構(gòu)建來自哪個(gè)發(fā)行渠道os.arch確認(rèn)是不是amd64。這條命令比java -version誠實(shí)得多它不看你 PATH 里寫了什么只看運(yùn)行時(shí)真實(shí)加載了什么。比這更硬的驗(yàn)證是直接看 JDK 根目錄下的release文件它是構(gòu)建時(shí)生成的元信息不受環(huán)境變量干擾。用記事本打開D:\jdk\jdk8u292\release里面會(huì)有JAVA_VERSION1.8.0_292、OS_ARCHamd64、OS_NAMEWindows這樣的鍵值對(duì)。生產(chǎn)環(huán)境要對(duì)比基線比的就是這個(gè)文件里的JAVA_VERSION和OS_ARCH而不是聽誰嘴上說“我裝的 8u292”。交接環(huán)境時(shí)我會(huì)讓同事把這兩條命令的輸出截圖發(fā)過來一眼就能確認(rèn)環(huán)境是否對(duì)齊省掉大量“我明明配好了”的口水戰(zhàn)。順便說一個(gè)更硬核的驗(yàn)證技巧如果你手里有一個(gè)編譯好的 class 文件可以用javap -verbose看它的major versionJava 8 編譯出來的 class 主版本號(hào)是 52??吹?52說明這個(gè)產(chǎn)物確實(shí)是 Java 8 工具鏈出來的看到 61那是有新版 JDK 交叉編譯過的運(yùn)行在 8u292 上就可能出問題。這個(gè)技巧用于驗(yàn)收“到底是誰編譯的”非常有效。我自己以前在 Windows 上裝 JDK 也是下載安裝器一路下一步直到某次梳理一個(gè)老項(xiàng)目的環(huán)境被藏在系統(tǒng)公共目錄里的舊 java.exe 折騰了大半天才發(fā)現(xiàn)真正生效的 Java 跟我想的根本不是一個(gè)。從那以后凡是 Windows 上要裝 Java我都堅(jiān)持固定目錄、zip 包、上面這組驗(yàn)證命令三件套。這套組合幫我避開了不少當(dāng)時(shí)覺得“查不出來”的玄學(xué)問題也讓我交出去的環(huán)境清單經(jīng)得起對(duì)賬希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取