Linux切換JDK版本實(shí)現(xiàn)方式
假設(shè)你的服務(wù)器上已經(jīng)手動(dòng)安裝了以下三個(gè)版本的 JDK(路徑僅為示例,請(qǐng)?zhí)鎿Q為你實(shí)際的路徑):
- JDK 8:
/usr/local/java/jdk-1.8.0_391 - JDK 11:
/usr/local/java/jdk-11.0.21 - JDK 17:
/usr/local/java/jdk-17.0.9
第一步:將新安裝的 JDK 注冊(cè)到 alternatives 系統(tǒng)
如果你是通過 yum/dnf 安裝的,系統(tǒng)通常會(huì)自動(dòng)注冊(cè)。但如果你是手動(dòng)解壓安裝的(如上一輪對(duì)話所述),你需要手動(dòng)告訴系統(tǒng):“嘿,這里有個(gè)新的 Java 版本,請(qǐng)把它加入候選列表”。
我們需要分別注冊(cè) java (運(yùn)行環(huán)境) 和 javac (編譯器)。
1. 注冊(cè) JDK 8
#/usr/local/java/jdk-1.8.0_391/ 這是你的服務(wù)器的jdk安裝路徑 # 注冊(cè) java 命令 (優(yōu)先級(jí)設(shè)為 108,數(shù)字越大優(yōu)先級(jí)越高,但交互模式下不重要) sudo alternatives --install /usr/bin/java java /usr/local/java/jdk-1.8.0_391/bin/java 108 # 注冊(cè) javac 命令 sudo alternatives --install /usr/bin/javac javac /usr/local/java/jdk-1.8.0_391/bin/javac 108
2. 注冊(cè) JDK 11
sudo alternatives --install /usr/bin/java java /usr/local/java/jdk-11.0.21/bin/java 111 sudo alternatives --install /usr/bin/javac javac /usr/local/java/jdk-11.0.21/bin/javac 111
3. 注冊(cè) JDK 17
sudo alternatives --install /usr/bin/java java /usr/local/java/jdk-17.0.9/bin/java 117 sudo alternatives --install /usr/bin/javac javac /usr/local/java/jdk-17.0.9/bin/javac 117
參數(shù)解釋
/usr/bin/java: 系統(tǒng)通用的命令路徑(用戶敲java時(shí)實(shí)際調(diào)用的位置)。java: 這個(gè)替代組的名稱。/usr/local/.../bin/java: 你實(shí)際安裝的 JDK 文件路徑。108/111/117: 優(yōu)先級(jí)。如果不進(jìn)行自動(dòng)切換,這個(gè)數(shù)字僅用于排序;在手動(dòng)交互模式下,選哪個(gè)完全由你決定。
工作流程圖解釋
當(dāng)你執(zhí)行完 --install 后,系統(tǒng)內(nèi)部發(fā)生了以下變化:
- 創(chuàng)建主鏈接:
/usr/bin/java->/etc/alternatives/java - 創(chuàng)建實(shí)際指向:
/etc/alternatives/java->/usr/local/java/jdk-17/bin/java(你注冊(cè)的路徑) - 記錄配置:在
/var/lib/alternatives/java文件中記錄下所有已注冊(cè)的版本列表和優(yōu)先級(jí)。
以后當(dāng)你運(yùn)行 sudo alternatives --config java 時(shí),系統(tǒng)就是讀取這個(gè)列表讓你選。一旦你選了新的版本,它只需要修改 /etc/alternatives/java 這個(gè)中間層的指向,瞬間完成切換,無需重啟。
常見錯(cuò)誤排查
錯(cuò)誤 1:link path already exists
- 現(xiàn)象:提示
/usr/bin/java已經(jīng)存在。 - 原因:該命令只能用于新增版本。如果
/usr/bin/java已經(jīng)被其他版本占用(或者已經(jīng)被注冊(cè)過),你不能重復(fù)執(zhí)行--install來覆蓋它。
解決:
- 如果是想更新已有版本的路徑:先用
--remove刪除舊路徑,再--install新路徑。 - 如果是想添加第二個(gè)版本:直接運(yùn)行命令即可,
alternatives允許同一個(gè)組名下有多個(gè)不同路徑的注冊(cè),它會(huì)自動(dòng)管理鏈接。注:如果提示存在,通常是因?yàn)槟阒耙呀?jīng)成功注冊(cè)過該路徑,無需再次注冊(cè)。
錯(cuò)誤 2:permission denied
- 原因:沒有加
sudo。修改/usr/bin和/etc/alternatives需要 root 權(quán)限。 - 解決:在命令前加
sudo。
錯(cuò)誤 3:優(yōu)先級(jí)設(shè)置混亂
- 現(xiàn)象:自動(dòng)模式下切換到了不想要的版本。
- 解決:手動(dòng)模式 (
--config) 不受優(yōu)先級(jí)影響。如果在自動(dòng)模式下,確保最高優(yōu)先級(jí)的數(shù)字給的是你希望默認(rèn)使用的那個(gè)版本。或者直接使用sudo alternatives --auto java讓系統(tǒng)自動(dòng)選優(yōu)先級(jí)最高的,或用--config強(qiáng)制手動(dòng)指定。
第二步:配置動(dòng)態(tài) JAVA_HOME(推薦)
為了讓 JAVA_HOME 隨 alternatives 切換自動(dòng)更新,在/etc/profile.d/java.sh文件中添加:
# 編輯Java.sh vim /etc/profile.d/java.sh
# 檢測(cè) java 命令是否存在
if [ -x "/usr/bin/java" ]; then
# 1. 動(dòng)態(tài)獲取 JAVA_HOME
# 核心邏輯:解析 /usr/bin/java 的真實(shí)路徑并去掉 /bin/java 后綴
export JAVA_HOME=$(readlink -f /usr/bin/java | sed 's:/bin/java::')
# 將當(dāng)前 JAVA_HOME 的 bin 目錄加入 PATH (通常 /usr/bin 已經(jīng)在 PATH 里,但這步是為了確保優(yōu)先級(jí)或完整性)
export PATH=$JAVA_HOME/bin:$PATH
# 2. 動(dòng)態(tài)配置 JRE_HOME (兼容 JDK 8 和 JDK 11+)
if [ -d "$JAVA_HOME/jre" ]; then
# JDK 8: 存在獨(dú)立的 jre 目錄
export JRE_HOME=$JAVA_HOME/jre
else
# JDK 9+: 沒有獨(dú)立 jre 目錄,JRE_HOME 通常指向 JAVA_HOME 本身,或者留空讓應(yīng)用自動(dòng)識(shí)別
# 許多現(xiàn)代應(yīng)用如果檢測(cè)到 JRE_HOME 不存在,會(huì)自動(dòng) fallback 到 JAVA_HOME
export JRE_HOME=$JAVA_HOME
fi
# 3. 動(dòng)態(tài)配置 CLASSPATH
# 注意:現(xiàn)代 JDK (9+) 其實(shí)不需要手動(dòng)設(shè)置 CLASSPATH 來包含 rt.jar,
# 但為了兼容舊腳本,我們保留邏輯,只在存在 lib 目錄時(shí)添加。
CP_PATH=".:"
# 添加 $JAVA_HOME/lib (主要針對(duì) JDK 8 的 tools.jar 等,JDK 9+ 下此目錄也存在但內(nèi)容不同)
if [ -d "$JAVA_HOME/lib" ]; then
CP_PATH="${CP_PATH}$JAVA_HOME/lib:"
fi
# 添加 $JRE_HOME/lib (主要針對(duì) JDK 8 的 rt.jar)
if [ -d "$JRE_HOME/lib" ]; then
# 防止重復(fù)添加 (當(dāng) JRE_HOME == JAVA_HOME 時(shí))
if [ "$JRE_HOME" != "$JAVA_HOME" ]; then
CP_PATH="${CP_PATH}$JRE_HOME/lib:"
fi
fi
# 去掉末尾多余的冒號(hào)并導(dǎo)出
export CLASSPATH=${CP_PATH%:}
fi然后保存后退出,執(zhí)行下面生效配置:
source /etc/profile.d/java.sh
驗(yàn)證是否生效
# 檢查當(dāng)前 Java 版本 java -version javac -version # 檢查 JAVA_HOME echo $JAVA_HOME # 查看 alternatives 當(dāng)前配置 alternatives --display java
第三步:交互式切換版本(核心步驟)
現(xiàn)在所有版本都注冊(cè)好了,你可以使用 --config 參數(shù)來選擇一個(gè)默認(rèn)版本。
1. 切換java(運(yùn)行環(huán)境)在終端輸入
sudo alternatives --config java
你會(huì)看到類似這樣的輸出:
There are 3 programs which provide 'java'. Selection Command ----------------------------------------------- + 1 /usr/local/java/jdk-1.8.0_391/bin/java * 2 /usr/local/java/jdk-11.0.21/bin/java 3 /usr/local/java/jdk-17.0.9/bin/java Enter to keep the current selection[+], or type selection number:
符號(hào)說明:
+: 表示當(dāng)前正在使用的版本。*: 表示上次手動(dòng)選擇的版本(如果沒改過,通常和+一樣)。
操作方法:
- 如果想切換到 JDK 17,直接輸入數(shù)字
3然后按 回車。 - 如果想保持現(xiàn)狀,直接按 回車。
- 如果想切換到 JDK 17,直接輸入數(shù)字
2. 切換javac(編譯器)注意
java和javac是分開管理的!切換完運(yùn)行環(huán)境后,務(wù)必也切換編譯器,否則可能出現(xiàn)“用 JDK 17 運(yùn)行,卻用 JDK 8 編譯”的奇怪錯(cuò)誤。
在終端輸入:
sudo alternatives --config javac
操作同上:看到列表后,輸入對(duì)應(yīng) JDK 版本的數(shù)字編號(hào)并回車。
第四步:驗(yàn)證切換結(jié)果
切換完成后,不需要重啟服務(wù)器,立即生效。請(qǐng)運(yùn)行以下命令確認(rèn):
# 1. 檢查運(yùn)行版本 java -version # 2. 檢查編譯版本 javac -version # 檢查 JAVA_HOME echo $JAVA_HOME # 查看 alternatives 當(dāng)前配置 alternatives --display java
常見問題與技巧
Q1: 我想刪除某個(gè)注冊(cè)的版本怎么辦?如果你卸載了 JDK 11,需要把它從 alternatives 列表中移除,否則會(huì)報(bào)錯(cuò)找不到文件。
# 語法:sudo alternatives --remove <組名> <完整路徑> sudo alternatives --remove java /usr/local/java/jdk-11.0.21/bin/java sudo alternatives --remove javac /usr/local/java/jdk-11.0.21/bin/javac
Q2: 如何查看當(dāng)前有哪些版本被注冊(cè)了(不切換)?
alternatives --display java alternatives --display javac
這會(huì)列出所有已注冊(cè)的 path 和當(dāng)前的狀態(tài),適合腳本檢查。
Q3: 為什么我輸入命令提示command not found?確保你使用的是sudo,因?yàn)樾薷?usr/bin下的鏈接需要 root 權(quán)限。普通用戶只能查看 (alternatives --display) 不能配置。
總結(jié)
在 CentOS/RHEL 上切換 JDK 的核心邏輯就是:
1. 手動(dòng)安裝 -> 2. alternatives --install 注冊(cè) -> 3. alternatives --config 選擇。
一旦注冊(cè)過,以后隨時(shí)可以通過第 3 步瞬間切換,無需修改任何配置文件或重啟服務(wù)。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Linux基礎(chǔ)之xargs命令的入門實(shí)例
你是否遇到過這樣的情況,需要一遍又一遍地對(duì)多個(gè)文件執(zhí)行同樣的操作?如果有那你肯定會(huì)深有感觸這是多么的無聊和效率低下。還好有種簡(jiǎn)單的方式,可以使用xargs命令解決這個(gè)煩惱。本文介紹了Linux基礎(chǔ)學(xué)習(xí)之xargs命令入門的相關(guān)資料,需要的朋友可以參考下。2017-12-12
Linux使用traceroute來進(jìn)行網(wǎng)絡(luò)診斷分析
在Linux系統(tǒng)下,traceroute是一個(gè)網(wǎng)絡(luò)診斷工具,用于追蹤一個(gè)數(shù)據(jù)包從源點(diǎn)到目的地所經(jīng)過的路由路徑,它通過向目的地發(fā)送一系列的 UDP 或 ICMP 數(shù)據(jù)包,并記錄每個(gè)數(shù)據(jù)包所經(jīng)過的路由器,來顯示數(shù)據(jù)包到達(dá)目的地的路徑,本文介紹了Linux如何使用traceroute來進(jìn)行網(wǎng)絡(luò)診斷分析2025-03-03
linux定時(shí)任務(wù)的一些相關(guān)操作匯總
這篇文章主要給大家介紹了關(guān)于linux定時(shí)任務(wù)的一些相關(guān)操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用linux系統(tǒng)組件具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
Linux實(shí)現(xiàn)添加新用戶及創(chuàng)建主目錄方式
這篇文章主要介紹了Linux實(shí)現(xiàn)添加新用戶及創(chuàng)建主目錄方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04

