☰
Linux下JDK卸载与安装全攻略:环境变量配置与常见问题排查
2026/9/29 1:06:39 网站建设 项目流程

搞Linux开发的朋友,几乎都绕不过JDK这道坎。不管是跑Java应用、搭Elasticsearch集群,还是折腾Spring Boot项目,JDK都是最底层的那块地基。但恰恰是这块地基,经常翻车——版本冲突、镜像源不对、环境变量配了不生效、卸载没卸干净导致新装的JDK各种报错,这些问题我几乎每次帮别人排查环境问题时都能遇到。

这篇文章我就把Linux系统里卸载和安装JDK这件事一次性讲透。从最基础的查看当前环境,到不同安装方式(rpm、yum/apt、tar.gz解压)对应的卸载和安装路径,再到JAVA_HOME、PATH、CLASSPATH几个关键环境变量的配置原理,最后附上我实际踩坑总结出来的问题排查清单。不管你是刚接触Linux的初学者,还是被JDK环境搞到头大的老手,这篇都能给你一个可以直接照着操作的完整方案。

1. 动手前的思路梳理:先搞清楚你机器上现在是什么状态

很多人一上来就急着找卸载命令或者下载JDK,这是最容易走弯路的地方。Linux下的JDK管理,第一步永远是"摸清现状",因为不同的安装方式,卸载和安装的路径完全是两套逻辑。

1.1 为什么卸载JDK比安装JDK更容易踩坑

安装JDK的教程遍地都是,但"卸载JDK"这件事,反而更难。原因很简单:Linux下的软件安装方式太杂了。有人用yum装的OpenJDK,有人从官网下载tar.gz包解压用的,还有人直接拿了别人打包好的rpm来装。这三种方式的卸载逻辑完全不同。yum装的有包管理器统一记录,卸得干净;tar.gz解压的,卸载其实就是手动删文件夹+清环境变量,但环境变量散落在好几个文件里,漏一个都会出问题。

我见过最典型的翻车案例是:同事装了新的JDK 17,但敲java -version始终显示旧版本。查了半天发现,旧版JDK的路径还残留在/etc/profile里,而新配置写在~/.bashrc中,两个文件的加载顺序导致PATH变量里旧路径始终排前面。这种情况在新旧版本切换时尤其常见,根本原因就是卸载阶段没有把旧环境变量清干净。

所以,卸载和安装从来不是两件独立的事,而是一个完整的"环境替换"过程:先彻底清除旧的,再干净地装新的,最后统一验证。

1.2 先摸清家底:查看系统里的JDK现状

动手卸载之前,先把下面这几条命令挨个跑一遍,搞清楚系统里的JDK到底是怎么装的、装在哪里、配置了哪些环境变量。

# 查看java命令的真实路径,注意可能是符号链接 which java # 如果which没输出,试试这个 type -a java # 查看java版本 java -version # 查看JDK具体安装目录 readlink -f $(which java) # 查看已安装的JDK相关rpm包(适用于CentOS/RHEL系) rpm -qa | grep -i jdk # 查看已安装的JDK相关deb包(适用于Debian/Ubuntu系) dpkg -l | grep -i jdk # 查看当前环境变量中的JAVA_HOME echo $JAVA_HOME echo $PATH

这几个命令跑完,你基本就能判断出自己机器的JDK状况了。这里有个细节值得注意:which java显示出来的路径,很多时候不是真实路径,而是符号链接(比如/usr/bin/java)。所以一定要配合readlink -f去找最终的实体目录,否则你删了符号链接指向的目录,但符号链接还挂在/usr/bin下面,系统一样能识别到java命令,只是版本可能已经不对了。

另外提醒一句:如果你发现系统里有多个JDK,先别急着一股脑全卸了。有些系统工具(比如Elasticsearch自带JDK、Maven依赖的JDK)可能同时存在,卸载前最好确认哪些是真正需要保留的。我建议按这个顺序判断——先处理环境变量里引用的那个,再处理/usr/bin下符号链接指向的那个,最后才处理剩余的残留文件。

2. JDK卸载实操:不同安装方式的清理路径

看完现状之后,就可以动手卸载了。我把Linux下JDK的卸载分三种情况讲,你可以根据自己的实际情况对号入座。

2.1 通过包管理器安装的JDK怎么卸

如果你是通过yum或者apt安装的JDK,卸载就相对简单,因为包管理器会帮你处理大部分依赖关系和文件清理。

# CentOS/RHEL/Fedora系列,先列出已安装的JDK包名 rpm -qa | grep -i jdk # 假设查出来的是 java-17-openjdk-headless,则执行 yum remove java-17-openjdk-headless # Debian/Ubuntu系列 dpkg -l | grep -i jdk apt remove openjdk-17-jdk-headless

这里有个小技巧:rpm -qa | grep -i jdk和dpkg -l | grep -i jdk查出来的包名通常很长,而且往往不止一个。比如装一个OpenJDK 17,会有java-17-openjdk、java-17-openjdk-headless、java-17-openjdk-devel等好几个相关包。我的经验是直接匹配版本号的主包卸载就可以,比如yum remove 'java-17-*',用通配符把所有相关包一起卸掉。当然用通配符之前先看清楚列表里的包名,别误删。

另外注意,有些系统默认自带了一个OpenJDK,比如CentOS 7默认带有OpenJDK 1.8。如果你打算换成Oracle JDK或者更高版本,这个系统自带的OpenJDK就是需要清理的对象。不过要留意:有些系统组件(比如图形界面工具)可能依赖系统自带的OpenJDK,强行卸载后可能引发其他问题。这种情况建议保留系统自带的,新装的JDK用独立路径,靠环境变量来控制实际使用的是哪个版本。

2.2 解压版JDK的正确删除姿势

从Oracle官网下载的jdk-17_linux-x64_bin.tar.gz,或者从镜像站下载的tar.gz包,解压后通常放在/usr/local/java、/opt/java或者用户自定义的目录。这种JDK的卸载最纯粹:删目录、清环境变量、清理符号链接。

# 假设JDK解压在 /usr/local/jdk-17.0.2 rm -rf /usr/local/jdk-17.0.2 # 清理 /usr/bin 下的符号链接(如果之前配置过) rm -f /usr/bin/java rm -f /usr/bin/javac # 如果是通过update-alternatives管理的符号链接(Debian系常见) update-alternatives --remove java /usr/local/jdk-17.0.2/bin/java update-alternatives --remove javac /usr/local/jdk-17.0.2/bin/javac

删目录这一步没啥技术含量,真正容易翻车的是环境变量清理。后面第2.3节我会详细讲。这里先着重点一个容易忽略的细节:很多人在解压版JDK上调用java命令时,其实是通过一个软链接(符号链接)实现的,就是在/usr/bin/java建立一个指向/usr/local/jdk-17.0.2/bin/java的链接。删掉了JDK目录后,这个软链接变成了"断链"。如果你没删掉它,后面新装JDK时,这个断链还占着/usr/bin/java这个名称,新的JDK装好了也可能因为路径优先级问题用不上。

2.3 环境变量是卸载过程最容易遗漏的部分

环境变量的清理,绝对是卸载JDK整件事里最容易出问题的一环。Linux下环境变量的配置散落在多个文件里,不同文件的生效范围和作用时机各不相同,很多人在清理的时候只盯着一个文件改,结果漏了其他的。

需要检查的文件主要有这几个:

  • /etc/profile:系统全局配置,所有用户登录时都会加载。
  • /etc/profile.d/*.sh:这个目录下的脚本会在/etc/profile中被循环调用,很多软件安装时喜欢在这里建一个单独的.sh文件存放JAVA_HOME配置。
  • ~/.bashrc:当前用户bash shell启动时加载,最常见的用户级配置位置。
  • ~/.bash_profile:当前用户登录时加载,通常会调用.bashrc。
  • ~/.zshrc:如果你用zsh,配置在这。
  • /etc/environment:这个文件比较特殊,是系统级别的环境变量定义,重启后对所有进程生效。

我在实际排查中发现,最容易被遗漏的是/etc/profile.d/目录下的JDK配置。有些安装脚本会自作主张地在这里创建一个java.sh文件,比如写入了export JAVA_HOME=/usr/local/jdk-17.0.2。你只改了/etc/profile,但每次登录shell时/etc/profile.d/java.sh还会重新把旧的JAVA_HOME导出来,导致新配置永远不生效。

清理方法很简单,用grep把所有配置文件里关于JAVA_HOME、PATH引用的行都找出来:

grep -n -i "jdk\|java_home" /etc/profile /etc/profile.d/*.sh ~/.bashrc ~/.bash_profile ~/.zshrc /etc/environment 2>/dev/null

找到之后,把对应的行删除或者注释掉。注意,grep出来的结果里可能包含一些注释文本,务必看清楚每行的实际内容再动手,别把其他软件的JAVA引用也误删了。

3. JDK安装实战:三种主流方式对比与选择

卸载干净之后,接下来就是装新JDK。Linux下装JDK的方式主要有三种:包管理器一键安装、tar.gz解压安装、rpm包安装。每种方式都有各自的适用场景,没有绝对的最优解,取决于你的需求和习惯。

3.1 下载JDK:官网还是镜像站

先解决"从哪下载JDK"的问题。Oracle JDK官方网站(oracle.com)的下载页面,Java 8和Java 11的老版本可以直接下载,但新版本下载时经常需要登录Oracle账号,这对很多国内用户来说比较麻烦。

实际使用中,我更多推荐从国内镜像站下载,速度和稳定性好得多。比较常用的有清华开源软件镜像站(mirrors.tuna.tsinghua.edu.cn)和华为云镜像站(mirrors.huaweicloud.com),它们在/Adoptium/目录下提供OpenJDK构建版。Adoptium(即Eclipse Temurin)是目前社区最认可的OpenJDK发行版,有标准的tar.gz和deb、rpm包,版本更新也及时。

这里解释一下Oracle JDK和OpenJDK的区别:两者在代码层面基本一致,Oracle JDK在Java 17之后也采用与OpenJDK类似的许可协议,绝大多数日常开发场景下两者没有明显差别。所以除非公司有明确规定必须用Oracle JDK,否则我建议直接用OpenJDK,省心且没有授权风险。如果你需要Oracle JDK,记住它的版本是长期支持版(LTS),目前主流是8、11、17、21这四个大版本。

下载的时候还有一个点要注意:JDK的版本号要和你的应用匹配。比如Spring Boot 3.x要求Java 17及以上,一些老项目还在用Java 8。装之前一定先确认需求,别装了个最新版结果项目根本起不来。

3.2 方式一:yum/apt一行命令安装

这是最省事的安装方式,适合对JDK目录位置没有特殊要求的场景。

# CentOS/RHEL/Fedora yum install -y java-17-openjdk-devel # Debian/Ubuntu apt install -y openjdk-17-jdk

装完之后,Java命令直接可用。yum或apt会自动配置好环境变量和符号链接,命令行里直接就能跑java -version。这种方式的好处是极快、零配置、后续卸载也干净。缺点是你对安装目录的控制力度小,JDK通常会被放在/usr/lib/jvm/下,如果应用对JDK路径有固定要求(比如你写死了/usr/local/java),这种方式就不合适。

这里有个小知识:CentOS/RHEL系装OpenJDK时,包名区分java-17-openjdk和java-17-openjdk-devel。前者是运行环境(含JRE),后者是完整开发环境(含javac编译器和tools.jar)。如果你要跑的是Java应用,只装前者够用;如果你是开发用,必须装-devel,否则没有javac命令。我自己装的时候基本都选-devel,一步到位,省得到时候要用javac发现没有。

3.3 方式二:tar.gz解压安装与JAVA_HOME配置

这是最灵活的安装方式,也是生产环境里最常见的做法。因为生产环境通常对JDK的安装路径有统一规划,比如统一放在/usr/local/java/或/opt/下。

# 1. 下载OpenJDK 17的tar.gz包(以Adoptium为例) wget https://mirrors.tuna.tsinghua.edu.cn/Adoptium/17/jdk/x64/linux/OpenJDK17U-jdk_x64_linux_hotspot_17.0.9_9.tar.gz # 2. 解压到指定目录 mkdir -p /usr/local/java tar -zxvf OpenJDK17U-jdk_x64_linux_hotspot_17.0.9_9.tar.gz -C /usr/local/java # 3. 查看解压后的目录名 ls /usr/local/java/ # 通常会得到一个类似 jdk-17.0.9+9 的目录 # 4. 设置环境变量 echo 'export JAVA_HOME=/usr/local/java/jdk-17.0.9+9' >> /etc/profile echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile echo 'export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar' >> /etc/profile # 5. 使配置立即生效 source /etc/profile

这套配置里,JAVA_HOME指向JDK的主目录,PATH把JDK的bin目录加到最前面,CLASSPATH指定Java类搜索路径。具体的环境变量含义,我会在第4节详细讲。

实际操作中,我不建议直接修改/etc/profile文件。生产环境服务器的/etc/profile是全局配置,改一个地方影响所有用户,而且出问题后不好回滚。更好的做法是在/etc/profile.d/目录下新建一个专门的文件,比如/etc/profile.d/java.sh,把上面的export语句放进去。这样配置模块化,查找和维护都方便,卸载时直接删掉这个文件就清干净了。

另外,强烈建议你在解压前先确认文件名。Adoptium的tar.gz包解压出来的目录名通常带版本号和+号,比如jdk-17.0.9+9。这个目录名后面配JAVA_HOME时要原样写对,别手抖打错。还有一个操作细节:解压完成后可以用mv把目录改成一个不带版本号的通用名,比如mv jdk-17.0.9+9 jdk-17,这样以后升级JDK时环境变量路径不需要变。

3.4 方式三:rpm包安装

主要适用于CentOS/RHEL系列。如果你从官网下载了.rpm格式的JDK安装包,用rpm -ivh直接安装即可。

# 安装 rpm -ivh jdk-17_linux-x64_bin.rpm # 验证 java -version

rpm安装方式的好处是:JDK被装到标准位置,rpm数据库会记录安装文件,卸载时用rpm -e能清得比较干净。但这种方式也有局限——它默认把JDK装到/usr/java/jdk-17,而且配置的是/usr/bin下的符号链接。如果你需要自定义安装路径,就还是用tar.gz方式更合适。

如果你是Ubuntu/Debian系统,对应的deb包用dpkg -i安装:

dpkg -i openjdk-17_linux-x64_bin.deb

4. 环境变量配置与验证:成败往往在最后一公里

这是整个JDK安装过程中翻车概率最高的一步。很多人JDK明明装好了,java命令还是用不了,或者java -version显示的版本不对,十有八九都出在环境变量配置上。

4.1 JAVA_HOME、PATH、CLASSPATH到底各管什么

三个变量各有各的职责,缺一不可。

JAVA_HOME:指定JDK的安装根目录。这个变量本身不直接影响java命令的可用性,但它对很多Java生态的工具至关重要。比如Maven、Gradle、Tomcat、Hadoop等都会去读JAVA_HOME来找JDK。如果只把java命令加到PATH,但JAVA_HOME没配好,Maven可能能跑,但Tomcat启动时就会报"找不到JAVA_HOME"之类的错误。所以这个变量一定要配,而且路径要指向JDK的真实目录,不能指向bin目录。

PATH:这是决定命令行里能不能直接敲java的关键。PATH=$JAVA_HOME/bin:$PATH的含义是:把$JAVA_HOME/bin这个目录放到PATH列表的最前面。这样系统在查找java命令时,会优先在JDK的bin目录里找到它。注意顺序很重要——如果你把$JAVA_HOME/bin放到$PATH的后面,而系统里还有其他地方也存在java命令,就会优先执行到别的java,版本就可能不对了。

CLASSPATH:指定Java类库的搜索路径。新版JDK(Java 9及以后)实际情况是,CLASSPATH的作用已经弱化了很多,JDK自身的类库都通过模块系统自动加载了。但在老项目里,还是会用.,这个点,代表当前目录)加上dt.jar、tools.jar的经典配置。我的建议是:新项目不需要CLASSPATH,配了也无妨;老项目如果依赖,就按老配置来。如果CLASSPATH配置不当,反而可能出现"找不到主类"或者"类冲突"的报错。

4.2 配置文件的加载顺序与生效时机

环境变量配置了不生效,这是最常见的求助帖。要理解这个问题,得先搞清楚配置文件的加载顺序。

以bash登录shell为例,加载顺序大致是:

  1. /etc/profile—— 系统全局配置,登录时最先读取。
  2. /etc/profile.d/*.sh—— 被/etc/profile循环调用。
  3. ~/.bash_profile—— 用户级登录配置。
  4. ~/.bashrc—— 用户级shell配置,~/.bash_profile里一般会调用它。
  5. /etc/bashrc—— 系统级bash配置。

理解这个顺序后,你就知道为什么有时候改了~/.bashrc后新开终端不生效、必须source一下才能用——因为新开终端的shell不一定走了完整的登录流程,尤其是用tmux、screen或某些终端模拟器时,环境变量是从父进程继承过来的,不会重新加载配置文件。

所以配置好环境变量后,有三种方式使其生效:

# 方式一:source命令,只对当前shell有效 source /etc/profile # 方式二:重新登录,所有shell都会重新加载 logout # 方式三:重启服务器 reboot

我的习惯是:配置完成后先用source验证环境变量和java命令是否正常,确认无误后再决定是否需要重开终端或重启。因为source对于当前shell的验证已经完全足够。

4.3 验证是否真的装好了

配置完环境变量后,不能光看java -version一个命令就完事。我建议按下面的顺序做一轮完整验证:

# 1. 查看JAVA_HOME是否指向正确 echo $JAVA_HOME # 输出应该是JDK的绝对路径,比如 /usr/local/java/jdk-17.0.9+9 # 2. 查看PATH里是否包含$JAVA_HOME/bin echo $PATH # 前面应该能看到 /usr/local/java/jdk-17.0.9+9/bin 在最前面 # 3. 验证java命令的真实路径 which java readlink -f $(which java) # 这两个命令的输出,最终应该指向你的JDK目录下的bin/java # 4. 验证版本 java -version # 确认显示的是你安装的版本 # 5. 验证编译器 javac -version # 6. 写个简单例子跑一遍 echo 'public class Hello { public static void main(String[] args) { System.out.println("JDK OK"); } }' > /tmp/Hello.java javac /tmp/Hello.java java -cp /tmp Hello

尤其是最后一步,写个最简单的类编译并运行,能同时验证javac和java两个命令、以及CLASSPATH是否正常。这一步能发现好多隐蔽问题。

5. 常见问题与排查实录

最后这部分,我把自己实际工作中遇到的高频问题整理出来,每个都附上排查思路和解决方案。这些坑我几乎都踩过,整理出来给各位省点时间。

5.1 终端能认出java?不,你确认过是在正确的shell吗

有次帮同事排查问题,他信誓旦旦说JDK装了,命令敲下去也正常。但我一执行java -version,完全不是他要的版本。后来发现,他用的shell是zsh,而配置写在了~/.bashrc里。bash和zsh的配置文件是各自独立的,~/.bashrc只在bash启动时加载,zsh根本不读。你在bash里跑java -version可能显示正常,但一旦切到zsh或者用zsh跑脚本,环境变量全都没了。

排查思路:先确认当前shell是哪个——echo $0或者echo $SHELL,然后去对应的配置文件里检查环境变量。如果用zsh,检查~/.zshrc;如果用bash,检查~/.bashrc和~/.bash_profile。还有一种情况,你用的终端管理器比如tmux,从bash环境进入tmux后创建的新窗格,环境变量可能继承的是老的,这时候敲source ~/.bashrc或者直接退出重进tmux就能解决。

5.2 环境变量配置失败的几类典型原因

  • 路径写错:JAVA_HOME写成了/usr/local/java/jdk-17.0.9+9/bin,多了一个bin。JAVA_HOME必须指向JDK的根目录,bin目录是PATH里拼出来的。
  • 引号问题:export PATH=$JAVA_HOME/bin:$PATH这条命令,如果$JAVA_HOME是空的,那PATH就被改成了/bin:开头,java命令肯定找不到。所以写之前先echo确认一下。
  • 权限问题:修改/etc/profile或者/etc/profile.d/java.sh需要root权限,如果用普通用户vim编辑后保存失败,配置根本没写进去。
  • 忘记source:改完配置文件直接跑java -version,当然没变化。必须先source或者重新登录。

排查这一类问题,最简单有效的方法是分步echo验证。比如:

echo $JAVA_HOME # 如果输出为空,说明变量没配上,去检查配置文件 # 如果输出有值但java命令还是找不到,去检查PATH echo $PATH

5.3 版本对不上?睁大眼睛看PATH顺序

这个坑前面提到过,新装的JDK 17,但java -version显示的还是老的OpenJDK 8。根本原因是PATH里老JDK的路径排在了新JDK前面。系统查找命令时是逐个目录扫描的,第一个找到的java就会执行。

排查方法:

# 查看当前java的实际路径 which java # 比如显示 /usr/bin/java # 然后查看这个路径指向哪里 ls -la /usr/bin/java

如果发现/usr/bin/java是一个软链接,用readlink -f看它最终指向哪。如果是老版本的路径,说明你安装新JDK时没有覆盖掉系统原来的符号链接。解决方法是直接删掉旧的软链接,重新建立指向新JDK的链接:

rm -f /usr/bin/java /usr/bin/javac ln -s $JAVA_HOME/bin/java /usr/bin/java ln -s $JAVA_HOME/bin/javac /usr/bin/javac

也可以检查一下是不是有/usr/lib/jvm下老的OpenJDK目录还在PATH里。这种情况在生产环境特别常见——系统自带OpenJDK和新装的JDK并存,环境变量还互相干扰。

5.4 权限问题与符号链接陷阱

tar.gz解压JDK时,如果解压后没有对目录做权限设置,普通用户可能无法执行bin/java。检查一下:

ls -l $JAVA_HOME/bin/java # 确认执行权限,应该显示 -rwxr-xr-x # 如果没有x权限,执行 chmod +x $JAVA_HOME/bin/java

还有一种情况:解压JDK是用root用户解的,目录的属主是root,普通用户执行java命令时如果目录无读权限,也会报权限不足。建议直接把整个JDK目录的属主改一下:

chown -R root:root /usr/local/java/jdk-17.0.9+9 chmod -R 755 /usr/local/java/jdk-17.0.9+9

符号链接这里也有个坑。某些脚本或工具在检测JDK路径时,会去解析/usr/bin/java这个软链接。如果软链接是"断链"状态(指向的目录已被删除),有些工具会直接报错。所以在删除旧JDK目录后,记得顺手清理失效的软链接。

5.5 常见问题速查表

我把上面所有问题的现象、原因、解决方法汇总成一张表,方便你遇到问题时快速对照。

问题现象可能原因排查/解决方法
bash: java: command not foundJAVA_HOME/PATH未配置或配置错误检查配置文件;确认路径写对;source生效
java -version版本不对PATH中存在多个JDK路径,顺序不对which java查看实际路径;清理旧路径和软链接
新终端不生效,source后才行shell配置文件未正确加载确认当前shell;检查对应配置文件(zsh/bash)
javac命令找不到只装了JRE没装JDK,或没装-devel包yum/apt安装openjdk-*-devel或完整JDK
解压后没有执行权限文件权限未设置chmod +x $JAVA_HOME/bin/java
卸载旧JDK后新JDK还是不能用环境变量残留或软链接断链grep排查所有配置文件;删除旧软链接
Cannot find JAVA_HOMEJVM相关工具读不到变量确认JAVA_HOME为JDK根目录,export语句无语法错误
Tomcat/Spring Boot启动失败版本不兼容或CLASSPATH异常确认JDK版本与框架要求匹配;检查CLASSPATH

我个人在实际操作中养成的习惯是:卸载和安装JDK时,每一步操作都用echo和which去验证,而不是机械地照抄命令跑完就完事。尤其是环境变量这种看不见摸不着的东西,多花一分钟验证,能省下后面好几个小时的排查时间。

这套流程下来,卸载和安装JDK就不再是玄学了。按部就班地操作,出现问题也基本都能按上面的排查路径找到原因。如果你在实操中还遇到其他奇葩问题,欢迎在评论里留言交流,我看到了会回复。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询