ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Linux下JDK卸载与安装全攻略:环境变量配置与常见问题排查

Linux下JDK卸载与安装全攻略:环境变量配置与常见问题排查 搞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.99 的目录 # 4. 设置环境变量 echo export JAVA_HOME/usr/local/java/jdk-17.0.99 /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.99。这个目录名后面配JAVA_HOME时要原样写对别手抖打错。还有一个操作细节解压完成后可以用mv把目录改成一个不带版本号的通用名比如mv jdk-17.0.99 jdk-17这样以后升级JDK时环境变量路径不需要变。3.4 方式三rpm包安装主要适用于CentOS/RHEL系列。如果你从官网下载了.rpm格式的JDK安装包用rpm -ivh直接安装即可。# 安装 rpm -ivh jdk-17_linux-x64_bin.rpm # 验证 java -versionrpm安装方式的好处是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.deb4. 环境变量配置与验证成败往往在最后一公里这是整个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类库的搜索路径。新版JDKJava 9及以后实际情况是CLASSPATH的作用已经弱化了很多JDK自身的类库都通过模块系统自动加载了。但在老项目里还是会用.,这个点代表当前目录加上dt.jar、tools.jar的经典配置。我的建议是新项目不需要CLASSPATH配了也无妨老项目如果依赖就按老配置来。如果CLASSPATH配置不当反而可能出现找不到主类或者类冲突的报错。4.2 配置文件的加载顺序与生效时机环境变量配置了不生效这是最常见的求助帖。要理解这个问题得先搞清楚配置文件的加载顺序。以bash登录shell为例加载顺序大致是/etc/profile—— 系统全局配置登录时最先读取。/etc/profile.d/*.sh—— 被/etc/profile循环调用。~/.bash_profile—— 用户级登录配置。~/.bashrc—— 用户级shell配置~/.bash_profile里一般会调用它。/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.99 # 2. 查看PATH里是否包含$JAVA_HOME/bin echo $PATH # 前面应该能看到 /usr/local/java/jdk-17.0.99/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.99/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 $PATH5.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.99 chmod -R 755 /usr/local/java/jdk-17.0.99符号链接这里也有个坑。某些脚本或工具在检测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/bashjavac命令找不到只装了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就不再是玄学了。按部就班地操作出现问题也基本都能按上面的排查路径找到原因。如果你在实操中还遇到其他奇葩问题欢迎在评论里留言交流我看到了会回复。
返回列表