ARTICLE DETAIL

资讯详情

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

JDK 11.0.15 Linux环境安装与配置:从tar.gz到多版本共存实践

JDK 11.0.15 Linux环境安装与配置:从tar.gz到多版本共存实践 简介Linux JDK 11.0.15 是为64位Linux系统打造的Java开发工具包适合需要在服务器或开发机上编写、编译、运行Java 11应用的开发者尤其适用于搭建Java运行环境与学习新版特性。该压缩包共含392个文件大小约161MB其中包含71个jmod模块文件、38个so动态链接库以及javac、java、jar等核心命令行工具与jconsole、jvisualvm等监控分析工具也涵盖license、policy等配置与授权文件可满足安装部署和本地开发需求。包内为官方标准目录结构解压配置JAVA_HOME与PATH后即可使用还附带classlist、release、security等环境元数据便于核对验证。目前已有803人学习下载适合初学者快速获取稳定版JDK也能帮助有经验开发者离线部署、复现问题或构建自定义运行时镜像。 最近在配服务器环境的时候正好又用到了这个包jdk-11.0.15_linux-x64_bin.tar.gz。说起来这版本不算最“新”但不少线上项目、中间件和老的构建工具对 JDK 11 的依赖已经到了“焊死”的程度很多团队宁愿把补丁版本从 11.0.14 升到 11.0.15也不愿意直接跳到 17 或 21。所以这个11.0.15的 tar 包看起来只是一个平平无奇的安装包实际却是运维和开发手里很常碰到的“固定答案”。这篇文章不打算写成那种贴一遍命令就完事的教程。我会把从拿到这个 tar.gz 到环境变量生效、再到后面多版本共存和踩坑排查的完整过程都拆开讲包括为什么目录要放在/usr/local/java、为什么用/etc/profile而不是/etc/profile.d、source之后到底发生了什么。如果你刚接触 Linux或者是第一次手动装 JDK按这个流程走一遍基本不会卡壳。1. 为什么还在用 11.0.15先把这个版本的来龙去脉搞清楚看到 11.0.15 这种版本号很多人的第一反应可能是“JDK 都出到 21 了还用这个干嘛”。但真实的生产环境不是追求最新版的地方。JDK 11 是 2018 年发布的 LTS长期支持版本Oracle 和 OpenJDK 社区对它的安全补丁和维护支持线拉得很长很多企业内部的统一 Java 版本基线就是 11。0.15 这个补丁版本属于 2022 年 4 月发布的 CPUCritical Patch Update修复了一批安全漏洞对于有等保或者内部安全规范要求的环境这几乎是必升的版本。另外要明确一点jdk-11.0.15_linux-x64_bin.tar.gz是官方发布的通用二进制包不是系统包管理器里那种编译好的发行版。它最大的好处是不依赖 yum、apt 这类包管理工具解压就能用方便统一版本尤其是内网离线部署的场景。坏处也明显环境变量得自己配卸载的时候得手动删目录不像 rpm 包那样能用命令管理得干干净净。1.1 从文件名能读出来的信息先养个习惯看到这种安装包就试着拆解文件名这一招在排查问题的时候特别管用jdk说明这是完整的 Java 开发工具包而不是只带运行时的 JRE也不需要单独去下载javac。11.0.15主版本 11补丁版本 0.15。如果你在代码里用到了某些 11.0.15 才修复的 JVM 参数或者行为变更那版本号就是决定性的。_linux目标平台是 Linux不能拿到 Windows 或者 macOS 上用。_x64适用于 64 位 x86 架构对应的 CPU 指令集是 x86-64。这个要特别小心现在 ARM 架构的服务器越来越多文件名里就会出现aarch64。如果你在 ARM 机器上去解压 x64 的包大概率能解压成功但一运行java -version就会报Exec format error。_bin.tar.gz表示这是一个通过 tar 和 gzip 双重打包压缩的二进制包。tar负责打包gzip负责压缩所以解压的时候要先解 gzip 再去解 tar一条命令tar -zxvf就能把两步都做了。1.2 Oracle JDK 和 OpenJDK 怎么选光有这一个 tar 包还不够你还需要知道它背后的发行方。jdk-11.0.15_linux-x64_bin.tar.gz默认指 Oracle 官方发布的 JDK 包。2019 年之后Oracle JDK 的许可协议从“免费用于个人/开发”变成了 Oracle No-Fee Terms and ConditionsNFTC许可意思是在开发、测试和大多数内部业务场景下可以免费使用但如果你把它作为 SaaS 产品的一部分交付或者再分发就得仔细看条款了。如果你的项目对许可比较敏感或者团队更偏好纯开源方案那就用 OpenJDK。OpenJDK 是 GPLv2 Classpath Exception 许可商用基本没有法律压力。11.0.15 这种版本的 OpenJDK 也可以在 Adoptium也就是 Eclipse Temurin或者清华镜像站找到。实际部署上Oracle JDK 和 OpenJDK 在这个版本上差别已经很小了除非你用到了特定的 Oracle 商业化特性比如 Java Flight Recorder 的某些旧行为否则日常编译运行几乎感受不到区别。我自己的习惯是服务器上用 OpenJDK 或 Oracle JDK 都行但必须保证小版本号和架构完全一致避免开发环境和生产环境因为补丁差异出现诡异问题。2. 安装环境的前置检查别急着解压先把这台机器摸清楚我第一次给生产服务器装 JDK 的时候直接就解压、配环境变量结果折腾了半小时才发现机器是 ARM 架构白忙一场。后来我养成一个习惯动手之前先花五分钟把系统信息查清楚这五分钟能省下后面一个小时的排查时间。2.1 确认系统位数和 CPU 架构在命令行执行uname -m常见的输出有这么几种x86_64Intel 或者 AMD 的 64 位处理器对应_x64包。aarch64ARM 64 位处理器对应_aarch64包。i686或者i38632 位系统这种情况比较少见但如果你还在维护老机器就得找 32 位版本的 JDK。如果uname -m输出x86_64那你手上的jdk-11.0.15_linux-x64_bin.tar.gz就是匹配的。同时看一下系统版本cat /etc/os-release我见过很多文章都推荐忽略这一步直接开装但实际工作中遇到过好几次“CentOS 7 自带了个旧 OpenJDK和新的 JDK 11 抢 PATH”的情况。先查清楚系统发行版和当前有没有别的 Java 环境比埋头解压重要得多。2.2 检查有没有装过别的 JDK用这几条命令快速排查which java java -version echo $JAVA_HOME如果有输出说明系统里已经存在 Java 环境。别急着卸载先用rpm -qa | grep jdkRHEL/CentOS或者dpkg -l | grep jdkDebian/Ubuntu查一下是怎么装的。如果是包管理器装的那环境变量通常已经配好了如果你又手动解压一个新的 tar 包最直接的结果就是java -version显示的还是旧版本因为 PATH 里排在后面的目录被优先命中了。另外要注意现在很多 Linux 发行版会在/usr/bin/java这种公共路径放一个软链接指向/etc/alternatives/java再由 alternatives 机制指向真正的 JDK 目录。看到有 alternatives 就别直接删文件用alternatives --config java去切换更安全。2.3 准备安装目录和临时目录我习惯把第三方手动安装的软件统一放到/usr/local下面Java 就放在/usr/local/javasudo mkdir -p /usr/local/java这个目录不需要预先特殊授权只要 root 权限能写就行。如果你解压的时候遇到Permission denied十有八九是目标目录没有写权限先sudo或者chown一下就好。下载目录我建议放在/opt或者直接用/tmp。/tmp的好处是不占根目录空间坏处是重启后可能被清理所以在解压完成之后tar 包本身放哪里其实无所谓。如果你是内网环境用管理员分发的安装包离线安装注意校验一下 md5 或者 sha256免得传输出错解压出来一个“残缺”的 JDK。3. 解压安装全流程从 tar 包到可用环境确认完这些前置信息后就可以正式开始安装了。这一节我会把完整的命令流程和目录规划一并讲清楚并解释每一步背后的理由。3.1 标准解压命令与目录规划假设安装包已经放到服务器上路径是/tmp/jdk-11.0.15_linux-x64_bin.tar.gz执行cd /tmp sudo tar -zxvf jdk-11.0.15_linux-x64_bin.tar.gz -C /usr/local/java/我们来拆解一下这条命令-z通过 gzip 解压。-x执行解压操作。-v显示解压过程方便你确认文件有没有完整释放出来。-f指定要操作的归档文件名。-C /usr/local/java/指定解压的目标目录。这个参数非常关键如果不加tar 包会在当前目录下解压出一个jdk-11.0.15文件夹有可能把一堆文件散落在/tmp里后面整理起来非常麻烦。解压完成后/usr/local/java/下面应该会多出一个目录名字就是jdk-11.0.15。接下来可以随手验证一下/usr/local/java/jdk-11.0.15/bin/java -version如果你能看到类似java version 11.0.15的输出说明这个 tar 包本身没有问题文件完整、权限也正常后续只剩环境变量配置这个环节了。这里我强烈建议不要在自己的家目录或者/root下面解压更不要解压完就扔在/tmp里直接配置环境变量。因为 Java 的很多工具需要通过读取JAVA_HOME来定位lib、bin、conf这些目录如果路径本身在/tmp一旦系统重启清理了临时文件整个环境就崩了。统一放在/usr/local/java既符合 FHS 的目录习惯也方便后续升级或者多版本共存。3.2 用软链接管理版本而不是改目录名解压完这个版本之后你可能会在未来遇到一个问题当 11.0.16 或者更高版本发布时你又下载了一个新的 tar 包目录名字从jdk-11.0.15变成jdk-11.0.16那环境变量里的JAVA_HOME是不是又要改一遍所以我现在更推荐的做法是做一个软链接比如sudo ln -s /usr/local/java/jdk-11.0.15 /usr/local/java/jdk11这样一来环境变量里统一写/usr/local/java/jdk11以后升级的时候只需要把新版本解压到jdk-11.0.16然后更新软链接指向即可sudo ln -sfn /usr/local/java/jdk-11.0.16 /usr/local/java/jdk11这种“目录名带版本号 软链接固定别名”的方式就是生产环境里管理多个 JDK 版本的一个非常朴素但高效的办法。不只是 Java像 Tomcat、Maven 这些依赖 JAVA_HOME 的组件只要软链接保持不变它们就永远不需要改动配置。4. 环境变量配置最简单也最容易出错的一步解压本身不会对系统产生任何“激活”效果如果你不配置环境变量那这个 JDK 就只是一堆躺在磁盘上的文件。Linux 里所有命令本质上都是靠 PATH 变量去找的不告诉系统该去哪里找java那你在终端里敲java -version就只会得到一个command not found。4.1 写入 /etc/profile 的标准写法我一般直接编辑/etc/profile因为这样可以给所有用户生效。当然你也可以在/etc/profile.d下新建一个java.sh两种方式本质上是一样的/etc/profile启动时会用source把/etc/profile.d/*.sh加载进来。用/etc/profile.d/java.sh的好处是职责单一卸载时候也方便我建议新手直接用它sudo vim /etc/profile.d/java.sh写入如下内容export JAVA_HOME/usr/local/java/jdk11 export PATH$JAVA_HOME/bin:$PATH export CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar这里解释三个变量的作用以及为什么这么写JAVA_HOME很多 Java 生态的中间件比如 Tomcat、Maven、Gradle都会读这个变量来定位自己需要的 JDK 路径。写软链接/usr/local/java/jdk11而不是真实目录是为了以后升级不用改这里。PATH把$JAVA_HOME/bin放在最前面是为了让系统的命令搜索顺序优先找到 JDK 11 的java。注意一定要放在$PATH的前面如果你写在最后面系统可能会先找到/usr/bin/java里的旧版 Java。CLASSPATH这个变量其实是给javac和java在编译/运行 class 文件时找依赖用的。JDK 9 之后模块化带来的变化很多但设置一个.表示当前目录是很多老项目的需求所以我这里仍按老规矩把当前目录加上避免一些集成项目因为找不到 class 而从报错。注意如果你用的是 JDK 9 之后的版本dt.jar和tools.jar这两个文件在 JDK 11 的 lib 目录下其实已经不存在了。我上面把这两行写进去主要是为了兼容旧项目可能有的习惯实际上即使不写这两行JDK 11 也能正常工作。如果你拿不准就直接只设JAVA_HOME和PATH最少足够用。写完后让配置立即生效source /etc/profile.d/java.sh4.2 验证环境变量是否生效接下来验证这一步会在很多地方踩坑我建议按顺序执行三条命令echo $JAVA_HOME java -version javac -version预期输出分别应该是/usr/local/java/jdk11、java version 11.0.15和javac 11.0.15。如果java -version显示的还是旧版本别慌大概率是以下两个原因之一/usr/bin/java这个软链接还在而且它的优先级高于$JAVA_HOME/bin。这种情况可以用which java看看到底是哪个路径在生效然后在/etc/profile.d/java.sh里把 PATH 设置改得更靠前或者直接处理掉旧软链接。source的配置文件不是登录 shell 会加载的那一个。如果你是通过图形终端打开的会话可能加载的是~/.bashrc而不是/etc/profile这时候你可以在~/.bashrc里也加一行source /etc/profile.d/java.sh或者直接重新登录一次系统。我在生产环境里更推荐“重新 ssh 登录一次”的方式这样可以确保当前会话与新配置完全同步而不是靠source在旧会话里打补丁。特别是当你后面还要启动 Tomcat 或者其他 Java 服务时干净的环境变量能够避免很多莫名其妙的困惑。5. 实测中高频遇到的几个坑这部分是我在这些年里被逼出来的经验。手动安装 JDK 并不是一件难事但它的坑往往出现在那些“看似和 Java 无关”的细节里。5.1 解压后 javac 能用了但 java -version 还是旧的现象你把JAVA_HOME指向了 JDK 11echo $JAVA_HOME输出也正确which javac显示的是/usr/local/java/jdk11/bin/javac但java -version却显示 1.8 或者其他旧版本。原因是 Linux 里有一条叫hash的 shell 缓存机制。当你之前已经执行过javabash 会把解析出来的路径缓存住之后你再配好了新 PATHshell 也没有重新去搜索而是继续用缓存里的旧路径。解决办法很简单手动清除命令缓存hash -r或者直接关闭当前终端、重新打开一个窗口。这个问题在排查时特别容易被人忽略因为你会觉得“我这个ls、cat都能用说明 PATH 没问题”但实际上只有java走了缓存。5.2 权限问题导致 Java 程序无法正常工作有时候你确实解压出了 JDK也配好了环境变量但一运行.sh脚本来启动 Java 服务就报Permission denied。这时候检查一下bin目录下文件的可执行权限ls -l /usr/local/java/jdk11/bin/java理想的输出里应该包含-rwxr-xr-x即有x权限。如果因为解压时的 umask、或者从 Windows 压缩传输导致权限丢失可以手动补上sudo chmod -R 755 /usr/local/java/jdk11755的含义是文件所有者可以读写执行同组和其他用户可以读和执行。这个权限模式对 JDK 目录来说已经足够。5.3 多版本 JDK 切换到底用 alternatives 还是手动改 PATH我在前面提到过很多 Linux 发行版会用alternatives也写作update-alternatives来管理软链接。如果你有多套 JDK可以用sudo update-alternatives --config java这个命令会列出系统里所有通过 alternatives 注册的 Java并允许你交互式地选择默认版本。不过这里有个坑alternatives管理的只是java这一个命令路径以及相关的一批命令它不会帮你设置JAVA_HOME和CLASSPATH所以即使你在 alternatives 里把 java 切到了 JDK 11echo $JAVA_HOME可能还是指向旧路径或者为空。更可控的方式是像我前面那样用一个软链接统一管理比如把JAVA_HOME指向/usr/local/java/jdk11需要切换的时候只修改这个软链接。这种方式比直接改/etc/profile要优雅得多因为它不需要重新加载环境变量文件只要之后新启动的进程都会读到最新的JAVA_HOME。进程已经启动的 Java 服务依然用的是旧路径这是 JVM 的宿命改完环境变量之后必须重启对应的服务进程这一点在“切换 Java 版本”时尤其容易踩。5.4 CLASSPATH 设置不当导致 NoClassDefFoundError我之前说过 JDK 9 之后dt.jar和tools.jar其实已经不存在了但还是会有人从老教程里复制那两行配置。如果你的CLASSPATH里写了一个不存在的路径虽然 Java 本身不会报错但某些集成开发环境或者老的构建脚本可能会在启动时报警告甚至会因为你把这个变量路径设置得不干净而找不到第三方库。解决办法如果项目没有特别强的历史包袱不建议配置CLASSPATH让 Java 依赖自身的默认 classpath 和构建工具Maven/Gradle来管理依赖会省掉很多额外问题。6. 安装完成后的收尾从验证到顺手维护当你配置完环境变量并确认java -version正确输出了 11.0.15 时安装工作其实已经完成了但还有一些收尾动作值得顺手做掉。6.1 校验核心工具是否齐全一个完整的 JDK 不只是java和javac还应该包含jar打包 jar 包的工具。jps查看当前用户启动的 Java 进程。jcmd向 JVM 发送诊断命令。jstack、jmap、jstat排查线上问题的性能工具。keytool管理密钥和证书SSL 相关的安全问题常会用到。你可以快速检查一下/usr/local/java/jdk11/bin下面这些文件是否存在。如果是从官网 tar 包解压出来的这些基本都在如果你是从某个精简的发行版镜像里拷出来的 JDK可能就会缺工具这时候就要重新确认安装包来源。6.2 顺手把 tar 包留档还是清理安装完成后原始压缩包是保留还是删除取决于你的磁盘策略。如果服务器磁盘空间宽裕建议保留在/opt或其他固定目录并记录下载来源和哈希值。这样以后出现文件损坏或需要重装时不必再去外网重新下载如果是在隔离内网这一步就更有价值。如果磁盘确实紧张直接删除/tmp下的压缩包也没有任何副作用因为 JDK 已经在/usr/local/java下正常工作了。6.3 一个我常用的最终验证习惯最后我还会再跑一个非常简单的 Java 程序来验证整个链路是否完整而不仅仅依赖java -versioncd /tmp cat Hello.java EOF public class Hello { public static void main(String[] args) { System.out.println(JDK 11.0.15 OK, Java home: System.getProperty(java.home)); } } EOF javac Hello.java java Hello这一步能确认编译器和运行时的配合是正常的也能顺带验证CLASSPATH里没有多余的东西干扰 class 加载。如果这个程序能顺利输出JDK 11.0.15 OK那你的整个 Java 环境基本算是彻底就绪了。装 JDK 这件事本身不算复杂但越是基础的操作越值得把每一步的原理“为什么这么做”讲透。比如目录规划、软链接、PATH 优先级、命令缓存、alternatives 机制这些知识不只是为了解决一次安装问题以后你再装 Tomcat、Maven、Spark 或者任何依赖 Java 的组件都会用到同一套思维模型。我最后一次在生产环境里装这个版本的 tar 包就是靠着“先看架构、再定目录、软链接固定 JAVA_HOME、最后用 hash -r 清理缓存”这个流程十几分钟就一台机器搞定了。希望这次分享也能让你的这一步更顺一点。本文还有配套的精品资源点击获取
返回列表