国产成人欧美一区二区三区vr_久久国产精品人人爽人人爽_国产精品永久免费播放_肉欲啪啪a∨无码精品一区二区_国产超短裙jk丝袜在线_亚洲AV片高清资源在线观看_国模无码一区二区三区久久_国产成年人未进视频_中文字幕无码精品夜_一区二区三区在线视频免费看_亚洲成AV人片在线观看网址_日本激情视频高清综合久久_亚洲午夜视频福利_国内大量揄拍人妻精品視_久久国产精品福利二区三区

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線(xiàn)實(shí)戰(zhàn)洞察。

Java環(huán)境配置自動(dòng)化:跨平臺(tái)JAVA_HOME/PATH與多版本切換實(shí)踐

Java環(huán)境配置自動(dòng)化:跨平臺(tái)JAVA_HOME/PATH與多版本切換實(shí)踐 搭過(guò)幾次新機(jī)器之后你會(huì)發(fā)現(xiàn)裝 JDK 那五分鐘從來(lái)不是問(wèn)題真正吃掉半天的是裝完之后那堆看不見(jiàn)的活環(huán)境變量寫(xiě)沒(méi)寫(xiě)對(duì)、終端里java -version和javac -version為什么對(duì)不上、IDE 里報(bào)找不到 JDK、換個(gè)項(xiàng)目又要切回舊版本、同事照著你寫(xiě)的文檔配了一遍結(jié)果怎么都跑不起來(lái)。這些事單獨(dú)看都是小事湊在一起就是典型的配置稅。我后來(lái)干脆把這套流程做成一個(gè) Java 環(huán)境配置自動(dòng)化工具給一個(gè)安裝包路徑剩下的探測(cè)、落盤(pán)、寫(xiě)變量、驗(yàn)證、出錯(cuò)回滾全部交給程序一條命令跑完新機(jī)器從零到能編譯不超過(guò)兩分鐘。下面就把這個(gè)東西的設(shè)計(jì)取舍、跨平臺(tái)實(shí)現(xiàn)細(xì)節(jié)和實(shí)測(cè)踩過(guò)的坑完整拆一遍適合手上有多臺(tái)開(kāi)發(fā)機(jī)、經(jīng)常給團(tuán)隊(duì)新人做環(huán)境交接、或者單純受夠了手工配 PATH 的同學(xué)照著復(fù)現(xiàn)。1. 手工配 Java 環(huán)境這件事真正耗時(shí)的從來(lái)不是裝 JDK先把問(wèn)題拆開(kāi)看。很多人對(duì)配 Java 環(huán)境的理解就是下載安裝包、下一步下一步、驗(yàn)證一下版本號(hào)。這個(gè)理解沒(méi)錯(cuò)但它只覆蓋了整條鏈路的第一步。剩下幾步才是返工的主要來(lái)源而且這幾步有個(gè)共同特征它們不會(huì)立刻報(bào)錯(cuò)而是延遲到某個(gè)不確定的時(shí)刻才炸所以你很難把故障和當(dāng)初那次配置動(dòng)作聯(lián)系起來(lái)。1.1 讓配置反復(fù)返工的五類(lèi)隱性成本我把過(guò)去幾年遇到的返工場(chǎng)景歸了個(gè)類(lèi)大概能覆蓋八成以上返工類(lèi)型表面現(xiàn)象真實(shí)原因變量作用域錯(cuò)位當(dāng)前終端正常新開(kāi)終端失效寫(xiě)進(jìn)了當(dāng)前會(huì)話(huà)而不是持久化配置文件路徑優(yōu)先級(jí)沖突版本號(hào)顯示的不是剛裝的那個(gè)舊 JDK 的 bin 目錄排在 PATH 更前面用戶(hù)級(jí)與系統(tǒng)級(jí)混寫(xiě)換個(gè)登錄賬戶(hù)就找不到 JDK只寫(xiě)了用戶(hù)變量腳本卻按系統(tǒng)變量讀變量引用被固化改 JAVA_HOME 后 PATH 完全不跟著變寫(xiě)入時(shí)把變量展開(kāi)成了字面量缺少完整工具鏈能跑 java 不能跑 javac裝的是運(yùn)行環(huán)境而非完整開(kāi)發(fā)包這五類(lèi)里面前三類(lèi)是寫(xiě)錯(cuò)地方第四類(lèi)是寫(xiě)壞格式第五類(lèi)是選錯(cuò)包。它們都不會(huì)在寫(xiě)入的那一刻給你任何提示全部要靠后續(xù)驗(yàn)證才能暴露。所以自動(dòng)化工具的價(jià)值不在于省掉復(fù)制粘貼路徑這幾秒鐘而在于把驗(yàn)證做成流程的一部分讓錯(cuò)誤在當(dāng)場(chǎng)暴露而不是三天后在構(gòu)建機(jī)上暴露。1.2 一次典型的交接事故復(fù)盤(pán)說(shuō)個(gè)具體的。某團(tuán)隊(duì)要給新加入的幾位開(kāi)發(fā)者準(zhǔn)備統(tǒng)一環(huán)境負(fù)責(zé)人寫(xiě)了一份圖文文檔步驟一共十一張截圖。前兩位照著做沒(méi)問(wèn)題第三位卡在構(gòu)建階段日志里是一行很普通的找不到符號(hào)。排查鏈路是這樣的先看java -version正常再看javac -version報(bào)不是內(nèi)部或外部命令也就是系統(tǒng)里只有運(yùn)行環(huán)境沒(méi)有編譯器確認(rèn)安裝包名稱(chēng)發(fā)現(xiàn)文檔里的鏈接指向的是運(yùn)行環(huán)境版本而前兩位之所以沒(méi)出問(wèn)題是因?yàn)樗麄冸娔X上原本就裝著別的開(kāi)發(fā)包java命令實(shí)際找到的是那個(gè)舊版本新裝的運(yùn)行環(huán)境根本沒(méi)有被使用。整個(gè)事故里有兩個(gè)獨(dú)立的錯(cuò)誤同時(shí)存在而且互相掩蓋——這正是手工配置最麻煩的地方錯(cuò)誤之間會(huì)互相遮蔽。如果把這件事交給工具做javac -version是必過(guò)的一項(xiàng)檢查第二個(gè)錯(cuò)誤立刻就會(huì)被攔下而PATH 里到底哪個(gè) java 會(huì)被優(yōu)先命中也會(huì)被顯式打印出來(lái)第一個(gè)錯(cuò)誤也藏不住。這就是我在設(shè)計(jì)這個(gè)工具時(shí)堅(jiān)持的第一條原則所有的隱式狀態(tài)都必須被顯式打印出來(lái)。2. 工具形態(tài)怎么選腳本、安裝器、還是常駐命令確定要做接下來(lái)第一件事是選形態(tài)。這個(gè)選擇直接決定了后面所有實(shí)現(xiàn)細(xì)節(jié)所以值得單獨(dú)聊一章。2.1 三種形態(tài)分別適合什么場(chǎng)景我評(píng)估過(guò)三條路線(xiàn)純腳本方案。寫(xiě)一份 shell 腳本加一份 PowerShell 腳本用戶(hù)按平臺(tái)各跑一個(gè)。優(yōu)點(diǎn)是零依賴(lài)、體積小、隨便改缺點(diǎn)是兩個(gè)平臺(tái)兩份代碼邏輯容易分叉而且腳本本身的可讀性和錯(cuò)誤處理能力有限尤其是需要做備份—寫(xiě)入—驗(yàn)證—回滾這種帶事務(wù)感的事情時(shí)腳本會(huì)寫(xiě)得很勉強(qiáng)。安裝器方案。打成平臺(tái)原生的安裝包雙擊下一步。優(yōu)點(diǎn)是體驗(yàn)最好缺點(diǎn)是打包成本高改一行邏輯就要重新出包而且安裝器在寫(xiě)環(huán)境變量這件事上并沒(méi)有比腳本強(qiáng)多少反而多了一層黑盒。常駐命令方案。用 Java 自己寫(xiě)一個(gè)命令行工具分發(fā)成一個(gè)可執(zhí)行的 jar 或者用包裝腳本調(diào)用。優(yōu)點(diǎn)是邏輯只寫(xiě)一遍跨平臺(tái)靠 Java 抹平而且這個(gè)工具的用戶(hù)本來(lái)就要裝 Java用它自己的生態(tài)解決它自己的問(wèn)題自洽。2.2 為什么最終選了以 Java 為主腳本兜底我最終的結(jié)構(gòu)是這樣核心邏輯全部用 Java 寫(xiě)跨平臺(tái)差異收攏到少數(shù)幾個(gè)策略實(shí)現(xiàn)類(lèi)里分發(fā)時(shí)給 Windows 配一個(gè).cmd啟動(dòng)器給類(lèi) Unix 系統(tǒng)配一個(gè).sh啟動(dòng)器兩個(gè)啟動(dòng)器只負(fù)責(zé)找到 java 并轉(zhuǎn)發(fā)參數(shù)不含任何業(yè)務(wù)邏輯。這么選有三個(gè)理由。第一這套東西的目標(biāo)用戶(hù)一定裝了某個(gè)版本的 Java否則他不需要這個(gè)工具所以用 Java 寫(xiě)不構(gòu)成額外的依賴(lài)負(fù)擔(dān)。第二環(huán)境變量的持久化寫(xiě)入本質(zhì)上是一次系統(tǒng) API 調(diào)用Java 里可以用ProcessBuilder調(diào)set/export這類(lèi)系統(tǒng)命令也可以用平臺(tái)原生命令控制粒度比 shell 腳本更細(xì)還方便統(tǒng)一做日志。第三出錯(cuò)回滾需要序列化和狀態(tài)管理Java 里做起來(lái)比純腳本舒服得多。有一點(diǎn)需要提前說(shuō)明啟動(dòng)器里找 java 這一步本身就有坑。如果用戶(hù)是第一次配環(huán)境機(jī)器上可能壓根沒(méi)有 java啟動(dòng)器就轉(zhuǎn)不起來(lái)了。我的處理是給啟動(dòng)器加一條降級(jí)路徑——先找JAVA_HOME找不到就看 PATH都沒(méi)有就提示請(qǐng)先用安裝包手工裝一個(gè)任意版本的開(kāi)發(fā)包再運(yùn)行本工具并且明確告訴用戶(hù)這一步只需要做一次。這是個(gè)產(chǎn)品層面的妥協(xié)繞不開(kāi)但要說(shuō)清楚。3. 跨平臺(tái)寫(xiě)環(huán)境變量三套系統(tǒng)的三套脾氣這是整個(gè)工具里最容易翻車(chē)的一章。三個(gè)平臺(tái)的持久化環(huán)境變量機(jī)制完全不同而且每一套都有各自的暗坑。3.1 Windows注冊(cè)表、命令行工具與 PATH 長(zhǎng)度Windows 上持久化環(huán)境變量市面上常見(jiàn)三種寫(xiě)法差別很大set只影響當(dāng)前命令行窗口關(guān)閉即失效。絕對(duì)不能用它做持久化。setx寫(xiě)注冊(cè)表持久化生效但它有兩個(gè)著名缺陷——單值超過(guò) 1024 字符會(huì)被截?cái)喽覍?xiě) PATH 時(shí)會(huì)把原本的REG_EXPAND_SZ類(lèi)型改成REG_SZ導(dǎo)致里面原本的%SystemRoot%這類(lèi)變量引用永久變成字面量再也展開(kāi)不了。這個(gè)坑一旦踩中修復(fù)起來(lái)非常麻煩因?yàn)樵袃?nèi)容已經(jīng)丟失了。[Environment]::SetEnvironmentVariable(name, value, scope)在 PowerShell 里調(diào)用底層 API行為比 setx 穩(wěn)妥不會(huì)截?cái)嘁膊粫?huì)把類(lèi)型改掉。所以我在 Windows 分支里只用第三種絕不碰 setx。核心代碼大致是這樣param( [Parameter(Mandatory $true)][string]$JdkHome, [ValidateSet(Machine,User)][string]$Scope Machine ) $javaExe Join-Path $JdkHome bin\java.exe if (-not (Test-Path $javaExe)) { throw 目標(biāo)目錄不是有效的開(kāi)發(fā)包根目錄$JdkHome } # 1. 先備份現(xiàn)有 PATH落到文件里 $stamp Get-Date -Format yyyyMMddHHmmss $backup Join-Path $env:ProgramData java-env-backup-$stamp.txt $oldPath [Environment]::GetEnvironmentVariable(Path, $Scope) $oldHome [Environment]::GetEnvironmentVariable(JAVA_HOME, $Scope) JAVA_HOME$oldHome | Out-File $backup -Encoding utf8 PATH$oldPath | Out-File $backup -Append -Encoding utf8 # 2. 拆段、清掉舊 JAVA_HOME 相關(guān)段、再拼回來(lái)保證冪等 $parts $oldPath -split ; | Where-Object { $_ -and ($_ -notmatch (?i)jdk) -and ($_ -notmatch %JAVA_HOME%) } $newPath ((%JAVA_HOME%\bin) $parts) -join ; # 3. 寫(xiě)入 [Environment]::SetEnvironmentVariable(JAVA_HOME, $JdkHome, $Scope) [Environment]::SetEnvironmentVariable(Path, $newPath, $Scope) Write-Host 已寫(xiě)入備份文件$backup Write-Host 新的 PATH 前 200 字符$($newPath.Substring(0, [Math]::Min(200, $newPath.Length)))幾個(gè)細(xì)節(jié)值得單獨(dú)點(diǎn)出來(lái)。第一PATH 里優(yōu)先寫(xiě)%JAVA_HOME%\bin這種變量引用形式而不是絕對(duì)路徑。這樣以后換版本只要改JAVA_HOME一個(gè)地方PATH 自動(dòng)跟著走不用再動(dòng)長(zhǎng)串。第二清理舊段時(shí)用了寬松匹配jdk和%JAVA_HOME%都當(dāng)成待清理目標(biāo)因?yàn)橛脩?hù)歷史配置里可能有各種寫(xiě)法。第三備份一定要做而且路徑要打印出來(lái)這是回滾的唯一依據(jù)。另外還有一個(gè)容易被忽略的點(diǎn)系統(tǒng)級(jí)變量和用戶(hù)級(jí)變量會(huì)合并合并順序是系統(tǒng)級(jí)在前、用戶(hù)級(jí)在后。也就是說(shuō)如果歷史遺留的用戶(hù)級(jí) PATH 里藏著一個(gè)舊 JDK 的 bin它會(huì)排在系統(tǒng)級(jí) PATH 后面但如果你往系統(tǒng)級(jí) PATH 前面插了新版本反而會(huì)出現(xiàn)新版優(yōu)先的假象——一旦用戶(hù)換了登錄賬戶(hù)順序可能又變。我的做法是兩個(gè)作用域都檢查一遍發(fā)現(xiàn)殘留就提示用戶(hù)確認(rèn)是否清理不擅自刪但一定要讓他知道。3.2 macOS版本探測(cè)與 shell 啟動(dòng)文件的分裂macOS 上有兩件事要處理。一是找到一個(gè)可用的 JDK 根目錄二是把變量寫(xiě)進(jìn)正確的啟動(dòng)文件。第一件事相對(duì)簡(jiǎn)單系統(tǒng)自帶一個(gè)版本探測(cè)器/usr/libexec/java_home -V它會(huì)列出所有已安裝的運(yùn)行時(shí)及其版本用它返回的路徑作為 JAVA_HOME 是最穩(wěn)的不要自己拼/Library/Java/JavaVirtualMachines/...這種路徑因?yàn)椴煌职l(fā)版的目錄結(jié)構(gòu)并不統(tǒng)一。第二件事才是麻煩。macOS 從某個(gè)版本之后默認(rèn) shell 換了用戶(hù)的啟動(dòng)文件可能是~/.zshrc、~/.zprofile、~/.bash_profile、~/.bashrc中的任意一個(gè)寫(xiě)錯(cuò)文件的表現(xiàn)是當(dāng)前窗口能用新開(kāi)窗口就沒(méi)了。我的策略是通過(guò)$SHELL判斷當(dāng)前 shell找到該 shell 實(shí)際會(huì)加載的那個(gè)文件——交互式非登錄 shell 讀~/.zshrc或~/.bashrc登錄 shell 讀~/.zprofile或~/.bash_profile兩個(gè)都寫(xiě)用帶標(biāo)記的段落包裹方便以后精確替換。帶標(biāo)記這件事很關(guān)鍵。我在文件里插入的是這樣一段# java-env-managed begin export JAVA_HOME$(/usr/libexec/java_home -v 17 2/dev/null || echo /path/to/jdk) export PATH$JAVA_HOME/bin:$PATH # java-env-managed end 有了這對(duì)標(biāo)記重跑工具時(shí)就可以按正則把舊段落整段替換掉而不是每次都往后追加一堆重復(fù)的 export。這是保證冪等的核心手段比檢查 PATH 里有沒(méi)有包含某字符串可靠得多。3.3 Linuxprofile.d 與 alternatives 的分工Linux 的服務(wù)端場(chǎng)景多需要區(qū)分給當(dāng)前用戶(hù)配和給整機(jī)配。給當(dāng)前用戶(hù)配寫(xiě)~/.bashrc或者~/.profile思路和 macOS 一致用標(biāo)記段落。給整機(jī)配我傾向于寫(xiě)到/etc/profile.d/下單獨(dú)建一個(gè)文件#!/usr/bin/env bash # /etc/profile.d/java_env.sh export JAVA_HOME/opt/jdk/current export PATH$JAVA_HOME/bin:$PATH用獨(dú)立文件而不是往/etc/profile里塞好處是卸載時(shí)直接刪文件就行干凈利落,不會(huì)把系統(tǒng)文件改花。注意這個(gè)文件需要可讀部分發(fā)行版還要求644權(quán)限才會(huì)被加載。至于update-alternatives很多教程推薦用它管理 java 命令。它確實(shí)能處理/usr/bin/java這個(gè)符號(hào)鏈接指向哪個(gè)版本但它只管命令鏈接不管 JAVA_HOME。而大量構(gòu)建工具和框架是靠讀JAVA_HOME來(lái)確定用哪個(gè) JDK 的。所以我的做法是兩者一起用alternatives 負(fù)責(zé)讓java、javac這些命令正確profile.d負(fù)責(zé)JAVA_HOME正確。只做前者會(huì)出現(xiàn)命令行版本對(duì)、構(gòu)建工具版本不對(duì)的詭異現(xiàn)象。4. 一鍵流程的骨架探測(cè)、落盤(pán)、寫(xiě)入、驗(yàn)證、回滾工具的主流程我定成五段順序不能換每一段都有存在理由。4.1 探測(cè)先確認(rèn)裝進(jìn)來(lái)的到底是什么第一步不是急著裝而是把你給的路徑驗(yàn)明正身。判斷依據(jù)不是目錄名而是實(shí)際執(zhí)行一次public record JdkInfo(Path home, String version, String vendor, boolean hasCompiler) {} public static JdkInfo probe(Path candidate) throws IOException { Path javaExe candidate.resolve(bin) .resolve(System.getProperty(os.name).toLowerCase().contains(win) ? java.exe : java); Path javacExe candidate.resolve(bin) .resolve(System.getProperty(os.name).toLowerCase().contains(win) ? javac.exe : javac); if (!Files.isExecutable(javaExe)) { throw new IllegalStateException(目錄下沒(méi)有可執(zhí)行的 java candidate); } String out runAndCapture(javaExe.toString(), -version); String version parseVersion(out); // 從輸出里抓版本號(hào) boolean hasCompiler Files.isExecutable(javacExe); return new JdkInfo(candidate, version, parseVendor(out), hasCompiler); }這里有兩點(diǎn)經(jīng)驗(yàn)。第一版本號(hào)必須從實(shí)際執(zhí)行的輸出里解析不能信目錄名。我見(jiàn)過(guò)太多目錄叫jdk-17實(shí)際里面是 11 的情況也見(jiàn)過(guò)解壓不完整、只有空殼目錄的情況。第二hasCompiler必須單獨(dú)檢查。前面那個(gè)交接事故就是栽在這上面。如果檢測(cè)到?jīng)]有編譯器工具應(yīng)該直接拒絕并給出明確提示而不是先配上再說(shuō)。順便說(shuō)一句解析java -version的輸出要小心它寫(xiě)到標(biāo)準(zhǔn)錯(cuò)誤流而不是標(biāo)準(zhǔn)輸出流很多實(shí)現(xiàn)里只讀 stdout 會(huì)拿到空字符串。這個(gè)細(xì)節(jié)我踩過(guò)一次調(diào)了半小時(shí)。4.2 寫(xiě)入與驗(yàn)證驗(yàn)證不是可選項(xiàng)寫(xiě)入按平臺(tái)分發(fā)前面幾節(jié)已經(jīng)講透。重點(diǎn)說(shuō)驗(yàn)證。我的驗(yàn)證分成四層任何一層失敗都觸發(fā)回滾層級(jí)檢查內(nèi)容為什么要有這一層進(jìn)程內(nèi)用絕對(duì)路徑執(zhí)行java -version、javac -version確認(rèn)包本身完好環(huán)境變量重新讀取持久化變量比對(duì) JAVA_HOME 是否等于目標(biāo)值確認(rèn)寫(xiě)入真的落地了而不是寫(xiě)到了會(huì)話(huà)里路徑解析啟動(dòng)一個(gè)新的子進(jìn)程在其中執(zhí)行where java/which java輸出所有命中項(xiàng)確認(rèn)優(yōu)先級(jí)和殘留構(gòu)建冒煙編譯一個(gè) hello world 并運(yùn)行端到端確認(rèn)工具鏈可用第四層看起來(lái)有點(diǎn)重但它是最有價(jià)值的一層。我做過(guò)統(tǒng)計(jì)前三層全過(guò)但第四層失敗的場(chǎng)景大概占百分之幾原因往往是磁盤(pán)上殘留了某個(gè)tools.jar或者CLASSPATH里有一條失效路徑。多花三秒省掉一次配完了還是跑不起來(lái)的扯皮非常劃算。驗(yàn)證必須在新的子進(jìn)程里做不能在本進(jìn)程里做。因?yàn)楸具M(jìn)程的環(huán)境變量在啟動(dòng)時(shí)就固定了你在 Java 里改了系統(tǒng)環(huán)境變量當(dāng)前 JVM 是看不到的。必須新起一個(gè)進(jìn)程它才會(huì)繼承最新的環(huán)境。這個(gè)細(xì)節(jié)如果沒(méi)處理好會(huì)出現(xiàn)工具說(shuō)配好了用戶(hù)開(kāi)新終端卻不行的經(jīng)典割裂。4.3 回滾備份文件就是生命線(xiàn)回滾邏輯很簡(jiǎn)單但在設(shè)計(jì)上有個(gè)細(xì)節(jié)要拿捏粒度。按變量粒度回滾——只恢復(fù) JAVA_HOME 和 PATH——比整文件恢復(fù)更合理。因?yàn)?PATH 是共享資源用戶(hù)在你這段時(shí)間里可能還裝了別的東西整文件覆蓋會(huì)把他剛裝的工具一起干掉。我的做法是寫(xiě)入前把兩個(gè)變量的原始值序列化到備份文件回滾時(shí)讀出來(lái)逐個(gè)恢復(fù)public void rollback(Path backupFile) throws IOException { Properties p new Properties(); try (var in Files.newInputStream(backupFile)) { p.load(in); } envWriter.set(JAVA_HOME, p.getProperty(JAVA_HOME, )); envWriter.set(PATH, p.getProperty(PATH)); log.info(已回滾到備份狀態(tài){}, backupFile); }備份文件我建議落在固定位置而不是臨時(shí)目錄因?yàn)榕R時(shí)目錄會(huì)被系統(tǒng)清理等到用戶(hù)想回滾的時(shí)候文件已經(jīng)沒(méi)了。Windows 上放程序數(shù)據(jù)目錄類(lèi) Unix 系統(tǒng)上放用戶(hù)目錄下的隱藏子目錄文件名帶時(shí)間戳只保留最近五份多了自動(dòng)刪。這套規(guī)矩看著啰嗦但真出事的時(shí)候能救命。5. 冪等性和多版本共存才是工具能不能長(zhǎng)期用的分水嶺這兩個(gè)特性決定了工具是用一次就扔還是能長(zhǎng)期待在你機(jī)器上。5.1 冪等跑一次和跑十次結(jié)果必須一樣非冪等的工具是災(zāi)難。用戶(hù)重跑一次PATH 后面多一段重復(fù)的 bin跑五次PATH 長(zhǎng)得溢出屏幕還得手工去刪。實(shí)現(xiàn)冪等的關(guān)鍵不是檢查有沒(méi)有而是先清理再寫(xiě)入。具體到 PATH就是把它按分隔符拆成數(shù)組過(guò)濾掉所有指向 JDK 的段和所有包含變量引用的 JAVA_HOME 段再把新段插到最前面最后拼回去。這個(gè)過(guò)程跑多少次結(jié)果都一樣。標(biāo)記段落是另一個(gè)層面的冪等。凡是我往用戶(hù)配置文件里寫(xiě)的塊都用成對(duì)標(biāo)記包起來(lái)重寫(xiě)時(shí)用正則精確替換private static final Pattern MANAGED Pattern.compile( # java-env-managed begin [\\s\\S]*?# java-env-managed end , Pattern.MULTILINE); public String upsert(String content, String block) { if (MANAGED.matcher(content).find()) { return MANAGED.matcher(content).replaceFirst( java.util.regex.Matcher.quoteReplacement(block)); } return content.endsWith(\n) ? content block \n : content \n block \n; }有個(gè)容易忽略的冪等盲區(qū)大小寫(xiě)和路徑分隔符。Windows 上同一個(gè)路徑可能有C:\Java\jdk17、C:\JAVA\JDK17、C:/Java/jdk17好幾種寫(xiě)法單純做字符串匹配會(huì)漏掉。所以比較前要先Path.toRealPath()歸一化再在 Windows 上做忽略大小寫(xiě)的比較。這一步不做用戶(hù)重跑十次就會(huì)得到十段重復(fù)內(nèi)容因?yàn)槊看味紱](méi)找到。5.2 多版本符號(hào)鏈接比寫(xiě)死路徑優(yōu)雅太多開(kāi)發(fā)中同時(shí)存在多個(gè) JDK 版本是常態(tài)。兩種模型我都試過(guò)。寫(xiě)死模型每次切版本就重寫(xiě) JAVA_HOME 為某個(gè)具體路徑。簡(jiǎn)單直接但缺點(diǎn)是你永遠(yuǎn)無(wú)法從環(huán)境變量看出當(dāng)前用的是哪個(gè)版本只能靠java -version現(xiàn)查而且構(gòu)建腳本里如果引用了具體路徑切完就斷。符號(hào)鏈接模型所有版本解壓到j(luò)dk/17、jdk/21、jdk/8之類(lèi)固定目錄然后維護(hù)一個(gè)jdk/current指向其中一個(gè)JAVA_HOME 永遠(yuǎn)寫(xiě)jdk/current。切版本只改一條鏈接環(huán)境變量一個(gè)字節(jié)都不用動(dòng)。# 類(lèi) Unix ln -sfn /opt/jdk/jdk-21 /opt/jdk/current# Windows需要管理員或開(kāi)發(fā)者模式 New-Item -ItemType SymbolicLink -Path C:\jdk\current -Target C:\jdk\jdk-21 -Force符號(hào)鏈接模型的好處是切版本變成原子操作失敗也不會(huì)留下中間狀態(tài)。缺點(diǎn)是 Windows 上創(chuàng)建符號(hào)鏈接需要額外權(quán)限普通賬戶(hù)可能會(huì)失敗。所以工具里要做降級(jí)檢測(cè)到權(quán)限不足就退回寫(xiě)死模型但要明確告訴用戶(hù)本次使用的是直接路徑模式切換版本需要重新運(yùn)行工具。這種降級(jí)策略是我認(rèn)為對(duì)一個(gè)工具是否成熟的判斷標(biāo)準(zhǔn)之一——不假設(shè)用戶(hù)環(huán)境十全十美。另外還有一個(gè)細(xì)節(jié)切完版本之后已經(jīng)在運(yùn)行的進(jìn)程不會(huì)自動(dòng)更新環(huán)境。IDE、終端、構(gòu)建守護(hù)進(jìn)程全部需要重啟。我一般在切換完成后直接打一段提示列出需要重啟的常見(jiàn)程序類(lèi)型雖然啰嗦但能省掉大量為什么切了還是舊版本的追問(wèn)。6. 實(shí)測(cè)踩坑與排查鏈路這一章都是真金白銀換來(lái)的。6.1 環(huán)境變量寫(xiě)對(duì)了IDE 卻堅(jiān)稱(chēng)沒(méi)有 JDK現(xiàn)象命令行里java -version正常工具驗(yàn)證也全綠但打開(kāi) IDE 新建項(xiàng)目提示找不到開(kāi)發(fā)包。排查鏈路先在終端確認(rèn)java -version——正常。說(shuō)明系統(tǒng)層面沒(méi)問(wèn)題。用工具自帶的診斷功能打印當(dāng)前 JAVA_HOME——正常。關(guān)鍵一步查這個(gè) IDE 進(jìn)程到底繼承了什么環(huán)境。Windows 上看進(jìn)程環(huán)境需要點(diǎn)手段最土但最有效的辦法是任務(wù)管理器里結(jié)束該 IDE 進(jìn)程重開(kāi)問(wèn)題消失。根因IDE 是從它啟動(dòng)時(shí)那一刻的父進(jìn)程環(huán)境繼承變量的。如果 IDE 在配環(huán)境之前就已經(jīng)開(kāi)著它拿到的是舊快照之后無(wú)論你怎么改系統(tǒng)變量它都不會(huì)刷新。更隱蔽的情況是Windows 上資源管理器本身也有環(huán)境快照某些從資源管理器啟動(dòng)的程序會(huì)繼承這份舊快照導(dǎo)致重開(kāi) IDE 都不好使必須重啟資源管理器進(jìn)程甚至重新登錄。解決方案寫(xiě)進(jìn)工具里寫(xiě)入環(huán)境變量成功后工具主動(dòng)檢測(cè)當(dāng)前有沒(méi)有正在運(yùn)行的常見(jiàn)開(kāi)發(fā)程序進(jìn)程有就提示建議重啟以下進(jìn)程xxx。這個(gè)提示我原本覺(jué)得多余實(shí)際用下來(lái)是反饋?zhàn)詈玫墓δ苤弧?.2 PATH 里有個(gè)更早的版本在搶現(xiàn)象工具說(shuō)配好了java -version卻顯示另一個(gè)版本。排查鏈路這條鏈路要看全量命中而不是只看第一條。Windows 上where java類(lèi) Unix 系統(tǒng)上which -a java把全部命中項(xiàng)和順序打出來(lái)問(wèn)題一目了然。我遇到過(guò)的真實(shí)原因包括某個(gè)工具安裝時(shí)往系統(tǒng) PATH 頭部插了自己的 bin用戶(hù)手動(dòng)加過(guò)一條絕對(duì)路徑的舊版本還有一個(gè)比較隱蔽的——PATH 里有兩條相同的段前面的那條指向已刪除目錄系統(tǒng)跳過(guò)它繼續(xù)往后找導(dǎo)致實(shí)際命中的是第三條。工具里的處理診斷功能輸出所有命中項(xiàng)并標(biāo)注每一項(xiàng)的來(lái)源系統(tǒng)級(jí)還是用戶(hù)級(jí)。同時(shí)在寫(xiě)入階段只要發(fā)現(xiàn)任何指向 JDK 的段殘留在 PATH 中不管位置在哪一律清理掉只保留工具自己插入的那一條。這個(gè)策略比較強(qiáng)硬所以我加了確認(rèn)提示讓用戶(hù)知道要?jiǎng)h什么。6.3 中文路徑與字符集帶來(lái)的連鎖反應(yīng)現(xiàn)象路徑里有中文字符時(shí)某些構(gòu)建工具報(bào)錯(cuò)或者工具自身的腳本執(zhí)行失敗。根因有兩層。第一層是腳本文件本身的編碼。Windows 的批處理默認(rèn)按系統(tǒng)編碼解析如果文件存成不帶 BOM 的 UTF-8里面的中文注釋會(huì)讓解析錯(cuò)位。第二層是子進(jìn)程輸出的編碼Java 在 Windows 上默認(rèn)按系統(tǒng)編碼讀子進(jìn)程輸出流遇到非 ASCII 會(huì)亂碼導(dǎo)致版本號(hào)解析失敗。處理方式一是把工具的所有腳本文件統(tǒng)一存成帶 BOM 的 UTF-8或者干脆在腳本里只用 ASCII 字符寫(xiě)注釋——我選了后者最省事。二是在 Java 里讀子進(jìn)程輸出時(shí)顯式指定編碼不要用平臺(tái)默認(rèn)值ProcessBuilder pb new ProcessBuilder(javaExe.toString(), -version); pb.redirectErrorStream(true); Process p pb.start(); String out new String(p.getInputStream().readAllBytes(), StandardCharsets.UTF_8);三是盡量勸用戶(hù)把 JDK 裝到純英文路徑下工具里做一次簡(jiǎn)單檢查發(fā)現(xiàn)路徑含非 ASCII 字符就警告。這條不是硬性攔截但提示的價(jià)值很大。6.4 權(quán)限不足與安全軟件攔截現(xiàn)象寫(xiě)入系統(tǒng)級(jí)變量時(shí)報(bào)拒絕訪(fǎng)問(wèn)或者執(zhí)行到一半進(jìn)程被殺。根因?qū)懴到y(tǒng)級(jí)環(huán)境變量需要管理員權(quán)限這一點(diǎn)在 Windows 上尤其明顯。而某些安全軟件對(duì)批量修改環(huán)境變量這種行為比較敏感會(huì)攔截或者延遲放行。處理方式工具啟動(dòng)時(shí)先做一次權(quán)限探測(cè)——嘗試往目標(biāo)作用域?qū)懸粋€(gè)同值的變量捕獲異常就能判斷有沒(méi)有權(quán)限。沒(méi)權(quán)限就明確提示請(qǐng)以管理員身份重新運(yùn)行或者改用當(dāng)前用戶(hù)作用域。絕不靜默降級(jí)因?yàn)橛脩?hù)級(jí)變量和系統(tǒng)級(jí)變量的作用范圍完全不同靜默降級(jí)會(huì)造成我配了但別的賬戶(hù)用不了的困惑。至于安全軟件攔截我的經(jīng)驗(yàn)是把工具的執(zhí)行過(guò)程做成有日志的每一步都輸出到日志文件。一旦被攔截用戶(hù)拿著日志能看出停在哪一步而不是面對(duì)一個(gè)沒(méi)有任何輸出的黑窗口反復(fù)重試。7. 交付前的自檢清單工具寫(xiě)完不算完還得能被別人正確使用。7.1 一份可以抄走的驗(yàn)收腳本每次配完我會(huì)跑這么一段做最終確認(rèn)。它同時(shí)覆蓋了環(huán)境變量的持久值和實(shí)際解析結(jié)果#!/usr/bin/env bash set -u fail0 check() { local label$1; shift if $ /dev/null 21; then echo [OK] $label else echo [FAIL] $label fail1 fi } echo JAVA_HOME ${JAVA_HOME:-未設(shè)置} check java 可執(zhí)行 java -version check javac 可執(zhí)行 javac -version echo --- java 的全部命中項(xiàng) --- which -a java 2/dev/null || where java 2/dev/null echo --- 版本一致性 --- jv$(java -version 21 | head -n1) cv$(javac -version 21 | head -n1) echo java : $jv echo javac: $cv if [ -n ${JAVA_HOME:-} ] [ -x $JAVA_HOME/bin/javac ]; then real$(readlink -f $JAVA_HOME/bin/java 2/dev/null || echo ) found$(command -v java) real_found$(readlink -f $found 2/dev/null || echo $found) if [ -n $real ] [ $real ! $real_found ]; then echo [WARN] java 命令實(shí)際指向 $real_found與 JAVA_HOME 不一致 fail1 fi fi [ $fail -eq 0 ] echo 全部通過(guò) || echo 存在失敗項(xiàng)請(qǐng)查看上方輸出 exit $fail最后那段一致性檢查是我后來(lái)加的之前吃過(guò)虧java命令和JAVA_HOME指向不同版本平時(shí)無(wú)感但構(gòu)建工具讀 JAVA_HOME、命令行讀 PATH兩邊行為不一致排查起來(lái)極其痛苦。把這項(xiàng)做成硬性檢查之后同類(lèi)問(wèn)題再?zèng)]出現(xiàn)過(guò)。7.2 一些只有自己上手才會(huì)知道的體會(huì)第一診斷信息的價(jià)值遠(yuǎn)大于自動(dòng)化本身。我現(xiàn)在回頭看這個(gè)工具真正幫我省下的時(shí)間大部分不是來(lái)自自動(dòng)寫(xiě)變量而是來(lái)自出問(wèn)題時(shí)能一眼看到全貌。所以如果你只做一個(gè)功能我建議做診斷而不是自動(dòng)寫(xiě)入。第二日志要寫(xiě)給兩種人看。一種是用戶(hù)他要看到現(xiàn)在在干什么、成功了沒(méi)有一種是你自己出問(wèn)題時(shí)你需要看到子進(jìn)程的完整輸出、變量的前后差異、每一步的耗時(shí)。這兩種需求不要合并成一個(gè)輸出流分成兩個(gè)文件或者兩種級(jí)別更清楚。第三永遠(yuǎn)不要信任已存在的狀態(tài)。工具每次運(yùn)行都應(yīng)該把當(dāng)前狀態(tài)完整讀一遍再?zèng)Q策而不是基于上次運(yùn)行留下的記錄做增量。用戶(hù)在這中間可能手工改過(guò)文件、裝過(guò)別的工具、換過(guò) shell任何緩存都可能過(guò)期。第四CLASSPATH 能不設(shè)就別設(shè)。我一開(kāi)始把CLASSPATH也納入了自動(dòng)配置范圍設(shè)成.;%JAVA_HOME%\lib之類(lèi)。后來(lái)發(fā)現(xiàn)這個(gè)做法在只寫(xiě).的場(chǎng)景下會(huì)覆蓋構(gòu)建工具自己的類(lèi)路徑計(jì)算邏輯引發(fā)莫名其妙的問(wèn)題?,F(xiàn)在我默認(rèn)不碰 CLASSPATH只在用戶(hù)顯式要求時(shí)才寫(xiě)并且在文檔里注明風(fēng)險(xiǎn)。第五給回滾留一條不用命令行的路。工具出問(wèn)題時(shí)用戶(hù)可能連終端都打不開(kāi)所以我在備份文件旁邊同時(shí)放一份純文本的手工恢復(fù)說(shuō)明里面就三行打開(kāi)哪個(gè)設(shè)置界面、把哪個(gè)變量改回什么值、刪掉哪個(gè)段落。這份說(shuō)明救過(guò)我自己一次。最后說(shuō)個(gè)可以繼續(xù)往下做的方向?,F(xiàn)在這個(gè)工具的版本探測(cè)是基于本地已有安裝包的如果再加上檢查某個(gè)版本是否已下載、沒(méi)有就按需獲取并校驗(yàn)完整性的能力就能覆蓋從裸機(jī)到可開(kāi)發(fā)的完整鏈路。不過(guò)這會(huì)引入網(wǎng)絡(luò)依賴(lài)和校驗(yàn)邏輯復(fù)雜度上一個(gè)臺(tái)階我暫時(shí)沒(méi)做等到手工確認(rèn)版本來(lái)源的環(huán)節(jié)真的成為瓶頸了再說(shuō)。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
91久久久视| 啊啊啊好舒服好爽啊啊啊视频| 黄站在线免费观看| 啊啊啊com| 国产激情视频在线观看| ?亚洲伊人伊成久久人综合网| 蜜臀99精品国产高清在线观看| 天美传媒AV国产在线| 天天操狠狠日夜夜干超碰撸com视频在线观看| 亚洲黄片免费在线播放| 大香蕉中文201| 久久亚洲人妻| 精品美女在线视频| 综合激情97 | 超碰地址久久| 哑洲在线| 偷拍片久久| 国产精品久久久久久久久久久久久久久久久久 | 中文字幕久久婷婷丁香五月天| 99re在线精品78| 91老司机在线视频免费观看 | 久久久久久久六六| 精品国产99| 欧美大香蕉在线观看| 岛国片在线观看视频亚洲| 琪琪精品免费一区二区三区| 国产又黄又粗又猛大片| 日本不卡二区| 日本乱人伦片中文三区| 岛国福利在线精品播放| 在线观看一级α片刺激高潮视频| 91丝袜在线观看| 变态综合色| 97视频新免费| 日韩有码中文字幕女同性恋| 国产400孕妇孕交群| 放黄片放3级黄片没穿衣服| 色97欧美| 91亚洲人| 成人国产视频在线观看| 婷婷超| 国产伦精品| 欧美亚洲91| 中文久久久| 日韩黄片影院| 久久6热视频免费观看| 成人aⅴ一区二区三区| 日日碰狠狠添天天爽超| 青青草依人大香蕉| 啊啊啊啊免费视频| 色视频蜜乳| 亚洲码在线中文在线观看| 久久精品人人做人人看| 国产日韩在线播放av| 无码不卡八戒| 麻豆啪啪啪视频| 99精彩视频| 国产农村妇女精品一| 国产60区。| 男人的天堂无码| 欧美春色| 一级黄色视频网| 午夜精品探花| 亚州再线| 久一区久久蜜桃| 欧美组图日韩亚洲中文字幕| 中文自拍欧美影视| 欧洲免费一区二| 丰满精品人妻少妇久久字幕| 欧美人人操人人插| 欧美老妇女内射网址| 夜夜夜夜爽| 天天网综合| 久久久久久久九九九九九九| 激情专区综合| 亚洲熟女乱综合一区二区三区| 欧美黑人91| 老女人综合| 先锋色眉乱伦资源| 天天影视网综合少妇| 樱花草社区www中国| 黄色成年| 色哟哟511老熟女| 91狠狠综合久久久久久| 96超碰网| 顶级丝袜熟女一区二区三区| 九九精品美女高溯喷水| 国产欧美黑人丰满在线| 97超碰超碰| 欧美另类自拍 | 97er欧美性| 亚洲性猛交| 少妇贴图| 国产三区免费在线观看| 天天射,天天操,天天爽-国内精品一区二区三区-成人AV | 17c嫩草51久久91嫩草| 在线观看无码三级少妇| 九九热免费国产视频婷婷伊人五月| 伊人991| 亚州男人天堂| AA丁香综合激情| 蜜臀99999| 大香蕉专区| 欧美专区第一页| 中文字幕欧洲有码| 亚洲国产午夜真人一级片中文字幕精品黄网站| 麻豆久久久久久久久丝袜| 综合自拍| 亚洲 欧美 手机在线观看| 黄色视频特级毛片| av在线一区二区三区| 在线国产探花| 91精品人妻五十路| 国产精品自在自拍视频| 人人操人人射人人干| 韩国毛片一区二区三区| 激情小说在线视频| 玖玖爱免费观看视频| 日本在线播放不卡一区| 日韩无码第3页| 97色欧州| 麻豆天美国美国产| 伊人骚琪琪亚洲天堂网站| 久久高清欧美国产| 天美久久久久| 成人情色一区二区| 女性91网站| 久久理论字幕视频| 少妇一级婬片免费放一级a性色.| 97视频在线免费播放| 亚洲精美粉嫩嫩泬在线观看| 蜜臀va69| 久都青青视频| 亚洲国产精品99久久久| 媚薬在线视频麻豆| 国产福利第一视频| 久久黄人人爽视频| 蜜桃中文字日产乱幕4区| 黑人精品XXX一区一二区| 啊啊好多水| 狠狠爱夜夜| 天美麻花大全视频| 69XX一中文字幕人妻91| 自拍啪啪视频| 少妇国产不卡| 视频黄色国产一级| 成人九九| 青青操在线亚洲视频观看欧美在线 | 精品亚洲一区在线观看| AV中文字幕剧情1区2区3| 不卡啪啪视频| 精品一级毛片在线观看| 天堂涩涩| 国产不卡片| 51久久夜色精品国产麻豆| 久久久久921| 强奸xx国产| 超碰精品| 日本综合久久| 午夜乱轮操逼视频免费看| 亚洲人综合| 国产精品国产自产拍高清AV| av凤凰久久久| 久久五十路熟女人妻| 中文字幕一区二区三区四五区| 午夜精品久久久久久久男人的天堂| 无码久久国产 | 在线观看视频91| 新久久AV| 另类小说欧美激情校园春色| 亚洲一级特黄大片在线播放91| 国产三级中文字幕粉嫩| 91肉丝| 丁香五月成人| 天天干天天狼在线视频| 天天射天天| 欧美日韩亚洲天堂| 一区二区播放| 嫩草伊人久久精品| 九九精品美女高溯喷水| 婷婷九月国产| 亚洲免费精品一区| 国产精品无码论坛| 操迟操逼在巾线Fre看| 国产99999| 色香综合天天影视综合| 精品视频专区| 97视频在线观看播放与子乱对白在线…… | 伊人欧美大香蕉视频| 色欲人妻一区二区在线| 极品粉嫩一区二区| 性色avv| 色色99| 日本国产高清色www视频在线| 九九九热| 免费家庭乱伦视频| 久久这里只精品免费福利| 草草草草视频| 国产97亚洲| 天美传媒精品久久视频| 欧美黑人168页欧美黑人167| 国产精品久久久久久9999| 国模不卡一本二本三电影| 中文字幕一二三区| 97超碰无码网| 天天干天天日天天射黄色大片| 久久久久13| 久久曰曰| www老逼91| 男人天堂站| 校园春色制服丝袜中文字亚洲| 婷婷丁香五月综合| 美女露胸露尿口| 亚洲AV无码天美传媒一区| 午夜天堂精品久久久久91| 五月婷婷大香蕉| 777奇米影视777四色| 精品久久久高清无码| 欧美激情性爱视频网站| 乱伦3P视频| 国产 亚洲 丝袜 制服| 日韩性爱电影一区| 婷婷五月天丁香| 91欧美| 久久xx| 日韩人体偷拍| 欧美午夜熟妇黑人精品91| 懂色影视久久| 春色综合网| 久久久新亚洲AV| 午夜亚洲WWW湿好大| ,成人免费啪啪视频| 亚洲欧美在线观看无码| 日本色色色视频| 人人透人人操| 亚洲精品一区二区三区新线路| 91丝袜在线观看视频在线观看| 97一区二区蜜臀| 中文字幕综合人妻| 久草在线| 伊人色综合网电影| av在线人气 | 蜜臀久久99精品久久久久久无删减 | 一区二区三区无卡视频在线观看| 加勒比性爱成人在线| 97色欧洲| 亚洲精品乱码线路中文字幕| 性影在线视频| 五月婷婷丁香六月| 91女优在线观看| 九九久久玖玖| 91天堂色男人的天堂| 蜜臀久久久久久999| 夜夜久久| a男人的天堂久久一级A毛片| 欧美精品日韩一区二区| 91丝袜激情在线| 国产 v乱码一区二| 国产一级做a爰大片免费久久| 国产真实野战在线视频| 超碰超碰95| 欧美综合 站| 超碰午夜| 九月婷婷综合| 久艹免费| 亚洲欧洲日韩国产自在线| 97天天爽| 男人综合网| blacked精品一区国产| 天堂九九九九九九九九九| 欧美国产操逼| 日本成人A片免费看| 久久9亚洲| 大香蕉99re| 在线观看AV片| 亚洲无限观看| 日本操逼二区| 亚洲资源站| 99精品成人免费看| 婷婷精品国产欧美精品亚洲人人爽| 亚洲成人贴图| 99精品在线观看| 久肏视频字幕| 69精品人人人人| 激情啪啪视频| 国产剧情AV不卡在线观看| 上床不卡网站| 日韩激情啪啪啪| 精品乱子一区二区三区99| 日日爱99| 久九9精品| 自拍二页| 激情小说日韩无码| 天堂av最新电影网| 乱伦av.com| 欧美激情综合| 自怕偷自怕亚洲精品| 中文字幕一区二区三区视频播放| 啊啊在线| 色五月av| 噜噜噜噜久久久精品免费| 免费A片三p视频| 日韩av不卡在线观看| 伊人96在线| 日韩欧美国产高清视频| 91久久婷婷| 韩国久久97| 蜜臀无码视频在线观看| 久久一区,青青青青草视频在线播放| 亚洲色宗合| 操香逼| 内射老妇BBWX0C0CK| 69视频福利导航| 国产精品分类在线观看| 国内外毛片在线观看| 亚洲操人| 国产野战露脸在线播放| 免看60秒涩涩视频| 天天干天天干天天| 天堂v无码免费视频| 中文字幕片| 亚洲va有码在线天堂| 综合大香蕉美。| 超碰AV在线| 久久AV无码AV| 亚洲中文字幕熟女| 中文字幕97色| 日本女人操逼| 在线毛片片免费观看| 精品一区二区三区四区外站 | 精久久久| 香蕉久久国产AV一区二区| 中文字幕人妻丝袜乱一区三区| 老女人爆菊| {男男暴菊gay无套网站| 偷拍99| 亚洲瓯美色图| 亚洲综合色婷婷| 蜜乳视频网站| 九九九九热只有精品| 久久久影院| 亚洲第2页| 欧美姓爱综合网| 欧美色一二三| 日韩AV电影网站| 神马久久久久久伦理片| 97碰| 99超碰碰| 啊嗯嗯啊好大好爽| 偷拍亚洲高清图片| 欧美人妻精品| 国产精品电影| 欧美激情中文字幕另类小说| 十八禁av无码免费网站APP| 日本大香蕉综合网| 欧美综合777| 欧美少妇大量自拍视频在线观看| 99自拍视频在线| av在线免费一区二区| 成人线上超碰| 亚洲人妻精品一区二区| 日日骚av| 久久风骚城市| 偷拍亚洲视频一区二区三区四区| 久久精品免视看国产成人﹣蜜臀av一区. 久久精品免视看国产成人,蜜臀av一区 | 欧美性爱一级操| 亚洲阿v天堂在线| 日韩大香蕉AV影片| 一起草三级AV电影在线观看| 久热99999| 欧美色图电影| 日韩国产欧美伦理在线| 亚欧高清在线| 欧美高清无码免费视频高清版| 日本色色网| 亚洲欧美一区二区网址| 超碰在线一区| 一区二区三区黄片免费观看| 丁香五月婷婷啪啪| 在线可观看的黄色网址| 午夜偷拍久久熟女| 亚洲一区二区三区AV无码| 国产成人 综合亚洲 天堂| 欧美天天综合网| 丰满人妻-区二区三区| 神马麻豆福利院| 亚州欧美在线| 久久久人妻| 亚洲自拍偷拍视频在线| 操国产逼| 亚州免费啪啪视频| 精品视频一区二区| 欧美色图 色综合图| 久久久久921| 射丝袜大香蕉| 婷婷激情丁香| 韩国一级做a久久久久| 亚洲视频中文一区| 久久欲| 国产视频一区二区三区在线免费观看 | 精品国产一区二区三区久久久蜜臀 | 91美女高潮| 国产日韩手机视频在线| 蜜桃视频成a人v在线| 插穴性爱视频在线观看| ?亚洲伊人伊成久久人综合网| 激情接吻视频久久久久久| 欧美人人AAA| 欧美亚洲日韩人妻在线观看| 久久精品天美| 亚洲色棕合| 诱惑网综合| 大香蕉综合网| 日韩无码黄色片| 91在线视频免费播放| 亚洲一区二区三区在线激情| 八戒午夜福利理论片| 美女一区二区国产精品| 91爽啪| 免费的av网| 国产视频小说| 97亚洲综合| 国产精品ⅴ无码大片在线看.| 操逼操逼逼操操逼91| 久久久久久人妻| 亚洲成人一二三区| 日本道人妻久久久在线不卡色视频| 超碰97男女| 国产精品国产亚洲区艳妇糸列| 亚洲毛片一级带毛片基地| 精品精品精品| 亚洲欧洲无码一区夜| 搡老女人老熟女91老熟女综合网| AV污污污污| 欧美后进式| 欧美激情久久久久| 蜜臀久久99精品久久久电影| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲天堂中文字幕无码男同| 亚洲色图第一页| 久久在线观看免费视频 | 91原创在线观看| 久久一本大香蕉 | 亚洲风情在线观看| 中文字幕欧美精品亚洲日韩蜜臀| 2024人人操人人摸| 午夜毛片高清免费不卡| 亚洲网自拍| 欧美激情久| 亚洲无 码A片在线观看麻豆| 一区二区三区视频在线观看免费| 国产精品一区二区a| 九一综合网| 国产一区二区在线播放| 九色婷婷| 久久亚洲婷婷| 国产女人高潮嗷嗷嗷叫小说 | 很很干很很操| 性爱av在线免费观看| 嗯嗯,好大,好爽,好骚| 1区2区3区视频| 国产自偷自拍一区| 人妻少妇无码| 久热九九| 无码二级三级| 女优视频第10页| 97在线视频观看免费| 九九精品99| 狠狠操狠狠燥| 亚洲AV无码AV吞精久久久久| 精品国产99| 最新av中文字幕高清| 日本福利社| 97资源亚洲| 丰满人妻一区二区三区| 精品视频久久| 日韩pv中文| 青青草国产欧美非洲黑人| 日本99热| 国产深喉视频一区二区| 欧美少妇大量自拍视频在线观看| 沈阳熟女高潮对白视频| 亚洲蜜臀懂色| 午夜啪啪片| 在线女人91| 试看60秒| 视频分类 国内精品| 亚洲精品国产熟女久久久| 日韩精品在线观看网站| 精品高清牛人盗摄一区二区三区中文字幕A片免费在线观看 | 国产网站在线播放| 国产自偷| 超碰日本97美女人妻人人玩人人爱| 9丨久久九九九| 四月丁香婷婷| 国产亚洲精品美女久久久m| 欧美黑人168页欧美黑人167| 五月天偷拍| 国产日韩精品suv| av东京热男人的天堂| 操逼1区| 大鸡巴久久| 蜜桃精品一区二区三区ww| 国产女同视频在线播放| 人人操肉肉| 一二三区操逼国产91| 亚洲丝袜二区| 17c在线成人免费A片观看| 干少妇视频| 日韩精品三区四区| 午夜电影在线观看无码专区| 精品免费囯产一区二区三区| 99 国产丝袜在线| av网站国产主播在线| 怡红院成人av| 激情五月天综合网| 国产亚洲日韩在线三区黑人| 日曰骚久久精品| 人人操天天爽| 久久人人爽人人爽人人片Ⅴ| 无遮挡男女激烈动态图| 97久久超碰国产精品| 欧美色图片91| 欧美精品1区2区3区| 久草尤物| 777超碰| 91 亚洲情侣偷拍 久久| 日本九九久久99播| 丁香五月综合| 欧美综合亚洲| 色婷婷综合久久久久中文国产精品一区中文字幕,国产福利电影一区二区三区 | 97se亚洲综合自| av东京热男人的天堂| 红杏大香蕉| 日本午夜精品理论片A级APP发布| 成人无遮挡毛片免费看| 校园春色 欧美| 超碰在线1234区| 久久久国产精品人妻丝袜| 欧美激情五月天| 人人摸人人干人人拍97| 亚洲色欲天天天堂色欲网女| 啪啪综合网| 亚洲欧美清纯| 麻豆天美在线| 欧美综合中文| 女人香蕉久久毛毛片精品| 91久久久老司机| 2000亚洲男人天堂| 中文字幕乱码人妻一区二区三区,99精品| 精品久热| 97色干| 综合婷婷| 丁香六月啪啪| 天美精品av| 大香交伊人网| 欧美 亚洲 制服 精品| 天天天天干| 丁香五月影院| 蜜臀久久99精品久久久久久久久| 狠狠综合网| 青青草操逼逼视频| 天天综合~91入口| 嗯嗯,啊啊,国产精品| 精品国产乱码久久久久久影片| 亚洲色综合| 人妻少妇久久久| 男人亚洲91首页在线| 白嫩嫩一区| 中文字幕在线观看AV| 美腿色图| 久久亚洲色图中文字幕| 精品国产综合久久福利,热99这里有精品综合久久,99热这里只有免费国产精品,精 | 一区二区 韩日AV| 96精品在线| 精品久久久久9999| 亚洲激情色片 | 奇米狠999| 日本护士高潮| 熟女精品一区二区三区| 久视频在线观看| 啊啊啊97视频| 麻豆国产视频精品观看| av天堂精品久久| 最新日产中文在线麻豆| 丁香六月综合激情| 九九九九九九九九九九九免费国产| 天天弄欧美| 啊啊啊久久久视频| 中文字幕后石码四区五区| 无码久久亚洲高清,| 亚洲精品毛片在线观看| 色情五月婷婷| 老师充足的奶水小说| 日本精品一区二区三| 91色宗合| 日本无码1| 亚洲丝袜二区| 极品AV网站在线观看| 国产后入式在线观看| 欧美亚洲天堂| 国产美女高潮叫床视频| 亚码激情| 精品免费成人久久| 日本色色视频网站| 中文字幕在线日亚洲9| 中文字幕视频2区| 色偷偷2020免费视频播放| 天堂无码| 操一区| 一区二区视频你懂的| 少妇天堂| 无码在线亚洲| 中出789在线视频| 狠狠干婷婷| 日韩专区数据列表-第3230页-精品国产一区二区三区香蕉 久久99熟女人妻中文字 | 国产精品蜜乳AV| 91超碰人人| 午夜操操操| 青青伊人这里只有精品| 亚洲偷拍自拍在线视频| 人妻久久| 精品国产丝袜一区二区三区乱码| 大香交伊人网| 毛片99-全集电影手机免费观看完整-B029AV| 一起草高清无码| 欧亚在线视频| 九九九精品一区二区无码| 超碰在线一区| 亚洲天堂,男人| 99久在线精品99re8| 九九精品99| 国产亚洲欧洲在线观看| 偷拍 亚洲 欧美| 狠狠干狠狠色| 天躁夜夜躁2021| 日韩精品中文字幕二区| 亚洲欧美日韩电影网站一区 | 岛国在线国产| 97人人中文网| 麻豆三极片| 玖玖97综合| 91爱网| 99热思思| 91青青草| 美女黄页| 亚洲性爱成人| 农村妇女精品一区二区| 26uuu性物| 加勒比海成人视频网| 丝袜 中出 制服 人妻 美腿 中文字幕| 看看小穴| 秋霞Av理论一级在线| 国产成人资源| 亚洲一区日韩精品中文字幕 | 超碰97人人乐| 精品久久久亚洲AV成人网站| 九久久精品| 蜜乳av首页| 99碰碰| 91n.欧美| www.狠狠操| 久久一二三四| 亚洲男人的天堂AV| 国产精品免费日韩| 尤物视频新赏网鲜网色诱网| 91麻豆一二三区| 在线观看A啊啊啊| 国产日韩欧美中文在线播放 | 十八禁成人网站在线观看| 青青草大香蕉在线视频| 亚洲精品无码成人久久久99| 久久精品中文字幕女同| 久久性爱城| 欧美啪啪色吧在线| 婷婷国产精品九区| 国产操操日韩三级黄| 久久网亚洲| 91国产精品在线看| 激情五月综合开心五月| 亚州高清av| AV九九| 韩国三级一线观看久| 亚洲凸凹超碰成人| 五月综合久久| 亚洲日本激情| a啊啊啊啊啊啊啊啊一区二区| 中文字幕精品一区二区精品| 国产精品久久aV| 免费男人的天堂| 精品国产91久久久久久一区黄无| 97干在线看| 黄色大香焦1级‘′‘| 91性感在线| 九草在线大香蕉| 九九综合色| 国产精品毛片?v一区二区三区| 亚洲精品久久久久久| 大香蕉免| 久久99网站| 久久五十路熟女人妻| 国产路线专区| 中文字幕伊人| 青娱乐av在线| 日本久久天堂| 欧美日韩国产中文精品字幕自在自线| 熟女人妻一区二区三区| 午夜精品久久999热蜜桃介男人用| 欧美国产日韩清纯唯美| 欧美日韩操操操| 亚洲日韩视频二区| 男人综合网| 91色综合色| 玖玖资源中文字幕制服丝袜| 长长久久88视频| 精品国产www久久| 先锋激情∨在线视频播放| 国产精品乱码久久久| 亚洲图片在线| 久久婷婷亚洲欧| 在线天堂999| 98色网| 亚洲夜夜欢无码一区二区| 人妻少妇被猛烈进入中| 欧美精品宗合| 超碰97亚洲| 久久久成人免费av电影| 99精品伊人| 欧美一二三区四五区| 亚洲五月丁香花狠狠干一区二区三区 | 久久久国产av美女私房| 亚洲国产综合图区中文字幕 | 欧美熟女少妇| 日日爽夜夜爽| www.夜夜| 99精品在线播放| 成人综合久久精品色婷婷| 国产偷拍自拍在线视频| 精品人体无圣光凹凸| 国产精品爱欲| 不卡av在线中文字幕| 91露脸熟女专区| 操婢日韩| 金莲网址| 五月天玖玖资源站| av资源在线观看少妇| 日本精品第一视频在'| 欧美人妻一区| 成人精品在线| 天天干天天做| 9/A片| 人妻天天爽夜夜爽爽| 少妇毛片久久| 国产综合久久久鬼色| 60秒免费小视频| 亚洲综合伊人| 亚洲色婷婷综合久久一区二区三区| 亚洲,欧美,综合网| 男人综合网| 91久久青青草原精品| 欧美性爱综合,免费| 成人性爱AV在线免费观看| 成人a大片在线观看| 国内毛片婷婷六月色| aⅴ日韩成人电影av在线免费看av大全 | 色蜜AV| 久久av网| 韩国毛片一区二区三区| 啊啊啊啊免费视频| 国产成人欧美精品在线| 久久久国产av美女私房| 国产精品免费美女视频| 天天干天天做| 啊啊啊啊操死我了| JIZZJIZZ亚洲女人被躁| 成年人黄色视频免费| 日韩欧美成人综合在线| 91精品伊人久久久大香线蕉91| 色综合色欲色综合色综合色综合| 久久久精品国产亚洲伊人| 密臀在线免费观看| 精品性爱久久视频| 欧色网址| 18禁中文字幕| 六月丁香五月婷婷| 天天澡天天爽日日av| 国产97av| 日韩性爱视频在线免费观看| 激情久久av一区av二区av| 久久久啊啊| 人人摸人人舔一区二区| 中文字幕三四区| 丁香五月综合| 欧美第38页| 亚春色色| 岛国黄| 丝袜六区| 人妻在线视频| 一区二区激情国产熟女| 后入式在线免费观看60秒| 一本大道青青| 久久久久久久强迫| 久久99亚洲精品久久99果| 日韩人妻资源在线看| 欧美 青青草| 欧洲综合色| 操逼操网| 亚州色图欧美| 国产强奸乱伦无码视频| 亚洲日韩精品在线播放| 人人噜夜夜操| 懂色Av| 色婷婷影院| 亚洲中字慕不卡| 欧美精品99久久久**| 蜜臀AV一区二区三区激情综合| 久久久一区二区三区麻豆| 欧美黄色大片在线观看| 亚洲一区操| 老鸭窝黄色视频网站| 91亚洲人| 深田咏美亚洲精品福利社| 超碰天天久久79| 久操视频在线观看| 色婷五月天| 91天天综合在线| 另类一区| 亚洲 另类 丝袜 自拍 动漫| 午夜视频黄| 久久手机视直播| 亚洲性网| 欧美综合骚| 色噜噜国产精品视频一区二区| 妺妺跟我一起洗澡没忍住| 青青草久草AV| 奇米狠999| 日本一久是| 亚洲第一精品在线视频| se,,,亚洲欧美| 九九精品99| 久热久操| 色偷偷男人的天堂麻豆| 国产操逼视频在线观看| www.99热在线只有精品| 午夜福利国产欧美日韩夜夜| 人妻在线臀日韩| 超碰97人妻免费在线| 一个人在线看的黄色电影网站| 酒色综合网| 成人国产视频在线观看| 97网站在线观看| www…国产操逼| J?P?NESEHD熟女熟妇伦| 99在线无码精品秘 入口黑人| 欧美日韩婷婷中文| 91九色蝌蚪在线观看| 九七毛片九九毛片| 黄aaaaaaaaaaaaaaaaaa色网站| 人妻少妇久久| 日本三级中国三级99人妇网站| 欧美九九九九九| 亚洲日本男人天堂网| 91丨九色丨国产丨人妻在线 | 男人的亚洲天堂| 人人干人人搞人人摸| 欧洲亚洲人妻无码高清久久三区四区| 激情综合五月天| 激情五月天中文字幕色| 嫩草伊人久久精品| 777奇米影视777四色| 天堂性色| 日韩 欧美 校园一区| 在线强奷到舒服的无码视频 | 丁香六月啪啪| 插入逼91| 欧美在线第五页| 好吊妞转入那个网| 人人操人人操人人人操| 亚洲,欧美,综合网| 高清不卡视频| 国产精选三级在线观看| 日日夜夜精品视频| 91爱做| 亚 欧 美 综合| 亚洲免费在线探花| 欧美中文综合| 丝袜亚洲91| 99国内精品| 午夜福利免费福利视频| 国产400孕妇孕交群| 久久精品视| GVH-003 母子姦 青木玲-麻豆视频,麻豆视传媒短视频网站入口,麻豆视传媒官网直 | 久久露脸国产老熟女| 欧美精品69性爱| 亚洲熟女一区二区| 激情亚洲天堂| 狠狠狠狠狠狠| 最新中文字幕精品在线| 亚洲婷婷丁香在线| 97精品视频在线播放| 嗯嗯嗯啊啊啊操的我好爽| 极品极品色影院| 天天色黄色影院天天操| 中文字幕在线免费观看| 超碰在线综合97| 久久久久久波多野吉衣高潮| 91制服丝袜| 韩国轻伦国内自拍一区| 日韩成人大片在线观看| 99老司机精品视频在线观看| 亚州综| 亚洲在线A| 超碰免费欧美7| 久久久久一本一区二区青青蜜月| 性吧在线视频| 色综合婷婷| 亚洲av影院在线观看| 91成人高清在线观看| 大香蕉综合网| 加勒比99999| 校园春色美腿丝袜 | 久久妇| 啊啊啊不要啊啊受不了了视频在线| 日日日日日| 亚洲欧美日韩综合在线尤物| 国产三级日产三级韩国三级| 人人 操人人 操人人| 精品蜜乳AV免费观看| 色图四区| 欧美高清色| 亚洲熟女av中文字幕| 亚洲丝袜少妇在线| 欧美亚洲首页| 亚洲欧美黄| 偷拍 亚洲 欧美| 激情欧美97| 91天天综合日韩欧美| 97亚洲中文| 凹凸精品熟女在线观看| 成人怡红院| 亚洲国产成人精品女人久久久| 9久久久久| 国产精品片| 97香蕉网| 欧美爆乳精品一区二区| 大香蕉乱级| 国产精品嫩草久久久久| 精品国产丝袜一区二区三区乱码| 亚洲国产精品9999在线观看| 超97在线精品视频| 亚洲欧美在线观看2021| 青娱乐日韩无码| 国产这里只有精品| 久久亚洲骚逼综合| 亚洲蜜臀懂色| 屁股久久久久久久久| 91熟女视频网| 超碰人妻97| 亚洲**2021在线观看| 日日插夜夜| 亚洲二区精品在线观看| 色色热| 久久精品中文字幕女同| 天美传媒av一区二区| 青青草中出视频| 96精品久久| 免费国产电影一区二区| 岛国毛片在线观看免费| 亚洲制服欧美另类内射| 大香蕉久久| 老熟女区| 日韩人人精品| 91综合网| 成人三一级一片aaa| 婷婷五月天基地| 91天天综合网,天天综合网| 久久久久久久久久久久欧美日| 精品人妻高清麻豆av| 久久产精品一区二区三区电影| 无码丰满熟妇一区二区浪潮AV| 國產尤物AV尤物在線觀看| 九色97| 91丝袜在线视频| 日躁天天爽爽| 台湾成人无码AV| 天天爱天天韩国日本牛牛牛牛| 午夜天堂网| 极品人妻少妇综合| 久久草草亚洲蜜桃臀| 国产成人无码网站在线视频| 冬京热男人的天堂| 欧美淫乱视频| 欧美v亚洲v综合v国产v妖精| 3p国产欧美99热| 欧洲中文字幕| 久久久青青草| 久操网无码在线| 中文字暮97| 激情文学小说一区二区 | 日韩精品免费高清视频在线| 国产原创自拍| 九九人妻| 中字幕人妻一区二区三区| 亚洲va综合va国产va中文| 欧美日动态视频| 毛片一区二区| 99久在线精品99re8热| 天天干人妻| 一级性爱视频免费观看 | 亚洲偷91色| 性色av网站| 久久系列| 黑人嘿嘿嘿超爽免费视频| 欧美午夜精品久久久久久3D| 91青青在线视频| 久久无码一区二区二三区性色| 久久思思热| 久久久内射良家| 免费无码国产精品v片在线观看| 夜夜一区二区| 日韩欧美久久婷婷网站| AA特级绝黄| 另类图片亚洲加勒比另类图片亚洲加勒比另类图片亚洲加勒比 | 国产91 丝袜在线播放 | japan日本高清乱xxxx| 夜夜高潮夜夜爽高清视频一| 欧美成人精品欧美一级乱黄一区二…| Blackedraw视频一区二区| 吉田爱美AV在线| 亚洲中文字幕熟女| 东京热激情视频一二三区| 久久久亚洲精品中文字幕人妻| 操逼操网| 天操天操夜操夜月操月年年操操| 天天看天天在线精品| 99xav| www.99色| 330Dv国产女人终合视频极品人与兽| 啪啪综合网| 亚洲射综合网| 超碰99热中文字幕| 日韩中文字幕2020| 超碰97国产欧美| 婷婷伊人綜合中文字幕小说| 997色在线| 性做久久久久久免费观看软件| 欧美日韩亚洲电影| 亚洲最新a在线观看| 中文久久96| 亚洲av淫乱| 偷拍亚洲情色| 色色色网站| 性天堂| 91美乳| 影音先锋视频在线| 欧美丝袜美女电影一二三四区| 色婷婷九月天天综合| 蜜桃午夜视频一区二区 | 中文字幕一区 二 区 三 四 五 区日 日 骚 | 国产吹潮女在线观看| 精品一二三区久久AAA片| 亚洲成人帖图| 精品久久視頻在线| 狠狠操使劲操| 大香蕉一人在线| 精品性爱一二三区| 99re黄| 曰本熟女视频| 大地资源在线观看中文第二页| 变态综合色| 60秒试看最爽10分钟网站| 亚洲日韩精品一区视频在线| 97在线观看视频| 极品丝袜无码| 欧美性爱日韩性爱| 欧美色交| 色婷婷蜜臀av| 亚卅熟女乱色| 秋霞网无码| 极品一区二区三区免费| 极品五月天噜噜| xxx0国产在线播放| 蜜臀99久久精品久久久久| 啊啊啊不要啊啊受不了了视频在线| 人人做人人妻人人夜视频| 女性91网站| 中文字幕欧美日本乱码一线二线| 亚洲国产第一页综合视频| 久综合国内精品自在自线| 99在线精品观看视频中文 | AV综合中文字幕干| 日韩精品三区四区| 少妇高潮流水av免费| 亚洲青青草| 国产原创精品| 久久香蕉综合一本到3atv| TS人妖另类精品视频系列| 欧美丝袜美女电影一二三四区| http://qxhbdz.com| 国产精品一级片在线看| 少妇色| 伊人嫩草| 超碰97最新人妻| 女同在线视频一区| 亚洲1区2区三区高清中文字幕| 久9无限国产| 久久噜| 第二页中文字幕| 97人人模人人爽人人| 午夜AV人气不卡| 男人的午夜天堂| 极品美女嘿咻| 内射中国少妇高清视频免费视频| 自拍偷拍 日韩无码| 久久久中文版| 殴美牲| www.婷婷| 色爱三区| 日韩 欧美 视频 在线 一区| 老司机午夜精品视频| 午夜精品久久久久久久第一页按摩| 9久精品视频在线观看| 久久久不能久久久久| 一区二区 韩日AV| 国产97色在线| 5278欧美一区二区三区| 成人三一级一片aaa| 日韩操逼性鲍| 操国产逼| 久久色网| 精品一区二区三区免费古装毛片香港三级日本三级人妇 | 日韩成人精品视频自拍| 日本人妻中文字幕| 日韩特级毛片免费观看全集| 免费国产视频| 国产剧情在线| 日韩射精| 丰满人妻一区二区三区免费| 日韩99999| 蜜臀99久久国产| 亚洲色人阁| 狠狠爱大香蕉| 五十路熟女人妻一区二区在线观看| 亚洲精品91| 97chaopengongkai| 久久少妇| 亚洲牲交| 国产精品久久久久久亚洲色欲| 亚欧无码线免费观看视频| a'v在线资源| 欧美精品久久久久久久丰满| 操逼无码操逼| 国产精品毛片?v一区二区三区 | 中文字幕制服欧美久久一区| 九九九午夜| 久久深夜无码| 97中文字幕色| 2017人人操,人人摸| 日本伦乱九九九综合| 国产一区二区成人av在线播放|