装JDK1.8这活儿听起来简单但放到Linux虚拟机环境下坑是真的不少。我见过不少同事直接在物理机上装两分钟搞定一换到VMware里的Linux就抓瞎要么文件传不进去要么环境变量配了不生效要么重启之后又回到解放前。这篇文章就把我实际踩过的坑和验证过的最稳流程从虚拟机准备到JDK安装再到问题排查一次性讲透。这篇文章适合谁看刚接触Linux的Java开发需要在自己电脑的虚拟机里搭一套开发环境的同学还有想在服务器上快速部署JDK8的运维新手。JDK1.8虽然出来很多年了但大量老项目、旧系统还在用它线上环境跑的最多的也是它掌握这个安装流程可以说是基本功。1. 整体设计与思路拆解1.1 为什么非要在虚拟机里装很多人不理解我本机Windows/Mac装个JDK不就行了吗为什么非要跑到Linux虚拟机里折腾这里涉及一个很现实的问题开发环境和运行环境不一致。你本地用的Windows线上服务器大概率是Linux。Windows下JDK的目录结构、环境变量写法和Linux完全不同你在Windows上写的启动脚本拿到Linux上大概率跑不了。而虚拟机里装Linux再装JDK能最大程度模拟生产环境你在虚拟机里验证过的部署步骤拿到服务器上基本能直接复刻。另外VMware虚拟机还有两个天然优势快照和隔离。装JDK之前打个快照配置搞坏了直接回滚不用重新装系统在虚拟机里怎么折腾都不影响宿主机。1.2 安装方案选型手动装还是包管理器装JDK1.8在Linux下的安装方式大致分三类我先把它们的优缺点摆出来安装方式优点缺点适用场景tar.gz压缩包手动安装目录可控、版本精确、可多版本共存需要手动配置环境变量需要精确控制JDK路径、多版本切换rpm包安装安装简单、自动配置命令目录固定、卸载相对麻烦RHEL系发行版快速安装yum/apt包管理器安装一条命令搞定、自动处理依赖版本可能不是最新、OpenJDK为主内网环境、对版本不敏感我的建议是如果你想老老实实在生产环境部署用tar.gz手动安装因为这个方式最“根正苗红”,你清楚地知道JDK装在哪个目录环境变量配在哪出问题好排查。包管理器方式适合图省事的场景但OpenJDK和官方JDK在某些小细节上有差异做老项目兼容测试时可能踩坑。1.3 版本选择为什么坚持JDK1.8JDK已经出到17、21了为什么还要装1.8因为存量市场的Java项目里JDK8的占比依然非常高。很多公司的核心业务系统跑在JDK8上升级JDK的代价远大于收益。而且Spring Boot 2.x系列基于JDK8非常成熟绝大多数中间件对JDK8的支持也最稳定。如果你只是自己学习测试装JDK8完全够用如果你要模拟公司的生产环境那更应该装8因为很多线上机器就是8。这也是为什么标题里明确写了JDK1.8我就顺着这个版本往下讲。2. VMware虚拟机准备与Linux系统安装2.1 虚拟机创建的硬件配置建议在VMware里创建虚拟机时硬件配置不是越大越好需要结合你的宿主机性能和实际用途来定。我一般这样配内存2GB起步如果要跑微服务测试或者编译大型项目给4GB再多就看你宿主机内存了。CPU2核足够编译时能吃满给4核会更快但虚拟机太吃CPU会影响宿主机。磁盘20GB是底线装完系统加JDK、常用工具后还能剩不少如果还要装数据库、中间件建议40GB。网络默认NAT模式即可不用改。这里有个经验磁盘建议用“单个文件”选项性能比“拆分成多个文件”稍好一点点虽然差异极小但能在提高IO性能上帮一点忙。另外创建虚拟机时操作系统类型一定要选Linux版本选对应的CentOS 7 64位或Ubuntu 64位否则后续VMware Tools可能装不上去。2.2 Linux发行版怎么选CentOS 7是很多老服务器的标配如果你公司的线上环境是CentOS虚拟机就用它保持一致性。Ubuntu Server也可以Debian系命令稍有不同但JDK安装步骤几乎一样。这里顺便提一下CentOS 8已经停止维护了新环境不建议再用CentOS 7虽然也进了维护期但存量最多相关资料好搜。如果追求长期稳定可以考虑Rocky Linux或Ubuntu LTS版本。本篇下面同时覆盖RHEL系CentOS和Debian系Ubuntu的要点方便你对号入座。2.3 网络模式与静态IP配置装完系统后很多人发现能上网但IP老变或者SSH连不上。这通常和网络模式配置有关系。VMware默认NAT模式下虚拟机通过宿主机共享IP上网能访问外网但外部不能直接访问虚拟机。如果你只是在自己电脑上做开发NAT足够如果你要把虚拟机当成局域网里的一台服务器让别人也能SSH进来就用桥接模式。NAT模式下DHCP分配的IP可能会变。为了后续用Xshell或者FinalShell连接方便建议把IP固定下来。CentOS 7的网卡配置在/etc/sysconfig/network-scripts/ifcfg-ens33网卡名可能不完全一样用ip addr查看实际情况核心是改三个地方BOOTPROTOstatic ONBOOTyes IPADDR192.168.xx.xx NETMASK255.255.255.0 GATEWAY192.168.xx.1 DNS18.8.8.8改完重启网络服务systemctl restart networkUbuntu的配置方式不同它在/etc/netplan/目录下配置格式是YAML改完后用netplan apply生效。这里有个我踩过的坑很多人忘了改ONBOOTyes重启系统后网卡没启动SSH连不上还以为是系统坏了。2.4 把JDK安装包传进虚拟机的几种方法JDK安装包通常在你宿主机上下载好了怎么传到虚拟机里我列几个我用过的方法VMware Tools拖拽装好VMware Tools后宿主机和虚拟机之间可以直接拖文件。这个最方便但需要先安装VMware Tools而且某些精简版系统比如CentOS minimal依赖库不全装VMware Tools会失败。共享文件夹在VMware设置里添加共享文件夹把宿主机某个目录共享给虚拟机虚拟机里挂载到/mnt/hgfs。这个稳定可靠适合大文件。SSH传输如果虚拟机开了SSH服务宿主机用scp命令直接传。这个适合你已经知道了虚拟机的IP而且网络通畅的情况。直接用wget在虚拟机里下载如果虚拟机能上网最简单的是直接在虚拟机里用wget下载JDK包省去传输环节。方法4其实最省事唯一的问题是JDK8的官方下载地址对直接wget不太友好需要带参数或者你有其他镜像源。后面我会讲怎么处理。3. JDK1.8安装实操全流程3.1 环境准备与依赖检查不管用哪种方式安装装之前都建议检查一下系统环境和已有JDK情况。先看系统架构JDK的安装包分x86和arm版本用uname -m确认uname -m一般输出x86_64就是64位下载对应的x64版本如果是aarch64就得下arm版。再看系统里有没有自带或遗留的JDKjava -version which java rpm -qa | grep java # RHEL系 dpkg -l | grep java # Debian系如果已经有OpenJDK但不是你想要的那个版本建议先卸载干净再装否则配置环境变量时容易出现“明明配了JDK8一执行java命令还是旧版本”的尴尬情况。卸载命令示例RHEL系rpm -qa | grep openjdk | xargs rpm -e --nodeps3.2 tar.gz压缩包手动安装推荐方式这是我最推荐的方式步骤虽然比包管理器多几步但完全可控。第一步创建统一目录。我习惯把JDK统一放到/usr/local/java下这个路径简短好记方便配置。当然你放到/opt下也行关键是保持统一。mkdir -p /usr/local/java第二步解压安装包。假设你已经把jdk-8uXXXX-linux-x64.tar.gz放到了/root目录或/tmp目录下cd /root tar -zxvf jdk-8uXXXX-linux-x64.tar.gz -C /usr/local/java/注意-C指定解压目标目录。解压完成后/usr/local/java下会出现一个类似jdk1.8.0_XXX的目录。这里建议先重命名为jdk1.8后面配环境变量好写mv /usr/local/java/jdk1.8.0_XXX /usr/local/java/jdk1.8第三步配置环境变量。这里有两个作用域可选配在/etc/profile里全局生效所有用户都能用配在~/.bashrc里仅当前用户生效。我建议测试环境配全局防止切换用户后又出现java命令找不到。用vi或vim编辑/etc/profile在文件末尾追加export JAVA_HOME/usr/local/java/jdk1.8 export PATH$JAVA_HOME/bin:$PATH export CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar第四步让配置立即生效不重启系统source /etc/profile第五步验证安装。这一步最重要java -version javac -version echo $JAVA_HOME正常输出应该是java version 1.8.0_XXX之类的内容。特别提醒javac -version也必须验证因为有的坑只装了JRE没装JDKjava命令能执行但javac没有。3.3 为什么要配CLASSPATH关于CLASSPATH这条配置网上争议挺大。在JDK1.5之后编译器不需要你手动指定CLASSPATH也能编译和运行普通项目所以很多人说不用配。但在我实际经验里老项目的构建脚本里可能会用到tools.jar不配CLASSPATH就可能出现“找不到tools.jar”之类的报错。配一条也不碍事关键是别配错。有些从网上抄来的配置写成了set classpath...那是Windows的写法放Linux里会直接导致环境变量解析异常极其容易踩坑。另外.:表示当前目录加上它以后编译某个目录下的Java文件时不用额外加-cp .对新手友好一些。3.4 rpm包安装方式速览在CentOS这类系统上也可以下载rpm格式的JDK安装包使用rpm命令安装rpm -ivh jdk-8uXXX-linux-x64.rpmrpm安装的好处是它会自动帮你配置好一部分环境JDK默认安装到/usr/java/jdk1.8.0_XXX目录下并且会注册到系统里执行java -version大概率直接可用。但如果你装过多个JDK版本系统会在多个Java命令之间切换需要手动指定默认版本alternatives --config java从列表里选择你想要的JDK序号按回车确认。这个命令同样适用于在多个JDK版本之间来回切换比反复改环境变量方便得多。3.5 用yum/apt快速安装OpenJDK如果你不挑版本只是需要一个能跑起来的JDK8包管理器一条命令就搞定CentOS系统yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-develUbuntu系统注意Ubuntu 20.04及以后的官方源里没有openjdk-8-jdk了只有11和17。想装8的话需要添加第三方源或者直接下载tar.gz包。如果你用Ubuntu 18.04或者加了源可以apt update apt install -y openjdk-8-jdk这种方式装出来的是OpenJDK不是官方JDK。OpenJDK和官方JDK在大部分场景下行为一致但老项目里如果用到某些只在官方JDK里提供的专有功能可能会有坑。还有一点包管理器装的OpenJDK环境变量有时不会自动配JAVA_HOME你还需要手动加一下。3.6 验证安装与检查PATH顺序很多新手死在环境变量“看似配了却无效”这一类问题上其实多半是PATH的顺序问题。假设你的系统里/usr/bin/java指向了旧版本而你新装的JDK在/usr/local/java下当你执行java时系统会按照PATH里从前往后的顺序去找。如果/usr/bin排在$JAVA_HOME/bin前面就会执行到旧版本。看当前生效的PATHecho $PATH如果你发现/usr/bin排在前边有一个简单办法新建一个软链接强制覆盖ln -s /usr/local/java/jdk1.8/bin/java /usr/bin/java但软链接方式在应对多版本切换时不灵活更推荐的做法是确认/etc/profile里把$JAVA_HOME/bin放在PATH的最前面然后重新登录终端。3.7 设置多个JDK版本共存与切换如果你电脑上需要同时保留JDK8和JDK17手动改/etc/profile会让人崩溃。我的做法是每换一个版本就改一次很不优雅。更好的方式是写一个函数放进~/.bashrc里function setjdk() { export JAVA_HOME/usr/local/java/jdk$1 export PATH$JAVA_HOME/bin:$PATH }切换时直接执行setjdk 8 java -version这个小函数是我实际用了很久觉得最顺手的方式。当然生产环境不建议这么干老老实实只装一个版本。4. 常见问题与排查技巧实录4.1 执行java报“command not found”这个问题的最常见原因有三个环境变量没配、source没执行、终端没有重新打开。排查顺序建议这样走确认JDK真的装好了检查/usr/local/java/jdk1.8/bin/java这个文件存不存在。确认环境变量内容有没有写错比如JAVA_HOME路径中间多了一个空格典型的低级错误但特别常见。执行source /etc/profile后再执行echo $JAVA_HOME看有没有输出路径。如果只在某个终端里能用换一个终端就失效说明那是你终端会话的问题重新打开终端即可。还有一个需要注意的细节如果你用的是sudo执行java命令而环境变量配在普通用户的家目录配置文件里sudo环境下是看不到的。这也是为什么我在测试环境建议直接配/etc/profile全局生效省得sudo时又出幺蛾子。4.2 wget下载JDK8安装包速度慢或者失败官方下载页面对直接wget不友好实际下载时会发现页面跳转、登录验证一堆事。我常用的办法是找可靠的镜像站点或者直接用浏览器的下载功能下载好了再往虚拟机里传。如果你非要用命令行下载需要加上Cookie参数但Cookie会过期这里不展开。更实用的一条经验是先确认虚拟机能不能正常上网用ping baidu.com测试这里只是举例连通性不代表推荐访问任何站点。如果通用包管理器安装OpenJDK最快避免折腾下载。另外很多镜像站提供jdk-8u版本的tar包选择一个延迟低的镜像就好。下载完成后核对文件大小如果解开时报“gzip: stdin: not in gzip format”多半是下载的页面不是真正的压缩包直接把下载地址复制错会导致这个结果。4.3 安装完java能执行但javac命令不存在这个问题的本质是你只装了JRE没装JDK。很多人在网盘或文章里下的包名带“jre”字样解压出来确实没有javac。所以下载安装包请认准文件名里带jdk的全称像jdk-8u202-linux-x64.tar.gz不要下成jre-8u202-linux-x64.tar.gz。还有一种可能你用的是包管理器只装了java-1.8.0-openjdk没装-devel包。java-1.8.0-openjdk只提供JRE运行环境java-1.8.0-openjdk-devel才会装上javac。所以前面给的那条yum命令我特意写全了两部分就是这个原因。4.4 配置完环境变量重启后失效环境变量配好了当时source一下能用重启系统后失效这是很典型的“配错了文件”问题。/etc/profile是登录时会加载的全局配置理论重启后依然生效但如果你的JAVA_HOME配在某个临时变量里比如直接在命令行里export过那当然只对当前会话有效。检查方法很简单grep -n JAVA_HOME /etc/profile ~/.bashrc ~/.zshrc 2/dev/null如果这几个关键配置里都没有JAVA_HOME那你的配置只存在于某个已经关闭的终端会话里重新配置就好。另外如果你用的是zsh或其他shell记得检查对应的配置文件比如~/.zshrc很多人只在.bashrc里改了换了shell之后完全不生效。4.5 虚拟机关机后IP变化导致SSH连接失败这个我在前面暗示过这里展开讲。VMware NAT模式下如果DHCP租约过期或VMware重新分配IP你的IP就会变。这时候你用SSH连之前保存的IP肯定连不上。第一个解决办法是固定IP参考2.3节改为静态配置。第二个办法是用VMware的vmnet网络特性配置端口转发这样哪怕IP变了也能通过固定端口连到虚拟机。但端口转发需要一定的网络知识新手老老实实配静态IP最稳妥。顺便说一下配置完静态IP后务必重启网络服务或者重启虚拟机验证一下网络能通。我见过很多人改了配置文件后没执行systemctl restart networkIP没变还误以为没配成功。4.6 JDK安装目录磁盘空间不足装JDK本身才几百MB但如果你在虚拟机上还要装数据库、IDE、日志文件20GB磁盘很容易被塞满。我遇到过装到一半提示No space left on device解压到一半就中断产生一堆半个文件非常恶心。处理办法先用df -h看各个分区的使用情况确认根目录剩余空间。如果空间不够有两个思路一个是扩容虚拟机的虚拟磁盘另一个是找个数据分区存放JDK。第二种更省事把JDK解压到/home或/data下空间通常比根分区宽裕。但要注意如果你把JDK放在一个后续可能单独挂载的分区上重启后要确认挂载正常否则就会上演“目录还在、内容是空的”的情况。5. 实操中值得养成的几个习惯和技巧5.1 装完立刻打快照我个人觉得这是整个流程里最值得养成的好习惯。装完JDK验证完java -version输出正常后回到VMware界面对虚拟机打一个快照命名“JDK8基础环境”。后面不管你怎么安装中间件、改系统配置出了问题一个回滚就能回到这个干净状态。快照不是银弹别把它当备份。快照文件会持续增大占用宿主机磁盘长时间使用的服务器虚拟机不适合留着大量快照。我的习惯是完成一个阶段的稳定配置后打新快照删除旧快照保持最多两三个。5.2 用检查脚本避免手滑新手在配置环境变量时容易多空格少斜杠一次配错后面排查半天。我习惯配完后马上执行一段验证命令echo JAVA_HOME$JAVA_HOME echo PATH$PATH java -version javac -version看到四行输出全部符合预期再往下走。如果发现JAVA_HOME为空先别急着怀疑JDK有问题大概率是配置没生效。还有一种情况你配置了JAVA_HOME但输出里没看到/usr/local/java这时候去看/etc/profile文件确认你加的几行真的保存了。vi/vim保存时的常见问题是按了Esc之后输入wq!结果因为输入法问题冒号变成中文冒号导致保存失败。这种情况遇到一次就长记性了。5.3 官方JDK与OpenJDK的选择如果你在模拟真实的生产环境我建议直接用官方JDK。虽然OpenJDK和官方JDK几乎一样但某些老项目用到的加密算法、字体库之类的差异会导致一模一样的代码在OpenJDK上表现异常。反正解决起来痛苦不如从一开始就保持一致。如果你只是为了学Java或者跑个小的教学项目OpenJDK完全够用能省去从官方渠道下载的麻烦。写在最后我最早学Linux时光装JDK就折腾了一晚上后来熟练了发现其实也就那几个核心点下载对包、解压到目录、配好环境变量、验证版本、留意PATH顺序。把这些动作形成肌肉记忆之后再装Tomcat、MySQL、Redis都是同一个套路本质都是解压、配置、验证三步走。最后分享一个小技巧无论用什么方式装JDK装完第一件事别急着写代码先用一个最简单的方法验证“当前用户”和“sudo用户”下java命令是否都存在往往能提前发现环境变量作用域带来的隐患。这个习惯帮我省了不少隔天起床发现“昨天明明能用今天怎么就不行了”的尴尬时间。