☰
Ubuntu 下安装 JDK 13.0.2 完整指南:环境变量配置与多版本共存
2026/10/12 8:06:24 网站建设 项目流程

1. 为什么 JDK 13.0.2 在 Ubuntu 上值得单独写一篇安装记录

JDK 13.0.2 这个版本号本身就带着一点"过渡期"的味道。它发布于 2020 年 1 月,属于 Java 13 的补丁更新版本,而 Java 13 又是一个非 LTS(长期支持)版本——生命周期只有半年,随后就被 Java 14 接棒。很多人会问:既然是非 LTS,为什么还要专门装它?答案往往很现实:某些老项目、某些教学环境、某些依赖特定语言特性的代码库,就是卡在 13 这个版本上。比如 Java 13 引入的文本块(Text Blocks)预览特性,在 13.0.2 里已经相对稳定,一些团队在当年就用它来简化多行字符串拼接,后来升级到 14 时又不想大动干戈,于是 13.0.2 就成了一个"够用且熟悉"的落脚点。

在 Ubuntu 上装 JDK,看起来是一件"下载解压配环境变量"的小事,但真正动手过的人都知道,坑并不少。Ubuntu 自带的软件源里通常只有 OpenJDK 的默认版本,而且版本号往往和你要的 13.0.2 对不上;用apt装出来的 JDK 路径分散在/usr/lib/jvm下,和手动安装的 Oracle JDK 或 AdoptOpenJDK 混在一起时,java -version到底调用的是哪一个,经常让人一头雾水。更麻烦的是,Ubuntu 从 18.04 到 22.04,默认的 shell 配置、update-alternatives机制、以及用户级环境变量加载顺序都有细微差别,同一套步骤在不同机器上可能一个成功一个失败。

这篇内容就是围绕"Ubuntu 下安装 JDK 13.0.2"这一件事,把版本选择、安装方式对比、环境变量配置、多版本共存管理、以及实际踩过的坑完整讲一遍。适合两类人看:一类是刚接触 Linux 环境、需要把 JDK 装明白的开发者;另一类是在维护老项目、需要精确锁定 13.0.2 这个版本、又不想把系统搞乱的老手。我会尽量把每一步"为什么这么做"讲清楚,而不是只丢几条命令让你复制。

2. 装之前先想清楚:JDK 13.0.2 的获取渠道与版本陷阱

2.1 Oracle JDK 与 OpenJDK 在 13.0.2 上的区别

JDK 13.0.2 这个版本,市面上主要有两个来源:Oracle JDK 13.0.2 和 OpenJDK 13.0.2。两者在功能上几乎一致,因为 Oracle JDK 本身就是基于 OpenJDK 构建的,差异主要在许可证和少量商业特性上。Oracle JDK 从 JDK 11 开始采用了新的许可协议,商用场景需要留意授权问题;而 OpenJDK 则是完全开源的,用起来没有这层顾虑。

对于 13.0.2 这个具体版本,Oracle 官方当时提供的是归档下载(Archive),因为非 LTS 版本在下一个版本发布后就会从主下载页撤下。这意味着你直接去官网首页是找不到 13.0.2 的,必须进到 Java Archive 区域。OpenJDK 这边,AdoptOpenJDK(后来并入 Eclipse 基金会,改叫 Eclipse Temurin)当时也提供 13.0.2 的构建包,文件名通常类似OpenJDK13U-jdk_x64_linux_hotspot_13.0.2_8.tar.gz。

我的建议是:如果只是本地开发、学习、跑测试,优先选 OpenJDK 13.0.2 的 tar.gz 包,解压即用,不涉及安装器,也不会有许可弹窗。如果项目明确要求 Oracle JDK,那就去归档区拿对应的.tar.gz,不要用.deb,原因后面会讲。

2.2 为什么我不推荐用 apt 直接装

很多人第一反应是sudo apt install openjdk-13-jdk。在 Ubuntu 20.04 上,这条命令有时能成,有时会告诉你"无法定位软件包"。原因在于 Ubuntu 的官方源对非 LTS 的 OpenJDK 版本收录并不完整,13 这个版本在很多镜像里根本没有。即使装上了,你拿到的也可能是 13.0.1 或 13.0.3,而不是精确的 13.0.2。

更关键的是,apt安装会把 JDK 拆散到/usr/lib/jvm/java-13-openjdk-amd64这样的路径下,并且自动注册到update-alternatives。如果你后续又手动装了一个 13.0.2 到/opt下,系统里就会同时存在两个"13",update-alternatives --config java里会出现多个候选,切换时容易选错。对于需要精确版本号的场景,手动下载 tar.gz 解压到固定目录,反而是最干净的做法。

2.3 下载时容易忽略的架构与校验问题

下载页面上通常有 x64、aarch64 等不同架构的包。如果你用的是树莓派或者某些 ARM 服务器,拿 x64 的包解压后执行java -version会直接报"无法执行二进制文件"。确认架构的命令是:

uname -m

输出x86_64就选 x64,输出aarch64就选 ARM 版本。另外,下载完一定要校验一下哈希值,尤其是从归档区拿的老版本包,网络传输出错的概率虽然低,但一旦文件损坏,解压时可能不报错,运行时才出各种诡异问题。校验命令:

sha256sum OpenJDK13U-jdk_x64_linux_hotspot_13.0.2_8.tar.gz

把结果和下载页给出的 SHA256 对比,一致再继续。

3. 手动安装 JDK 13.0.2 的完整操作链路

3.1 选择安装目录与解压

我习惯把手动安装的 JDK 放在/opt/java下,按版本号建子目录,这样多个版本互不干扰。先建目录:

sudo mkdir -p /opt/java

然后把下载好的 tar.gz 解压进去。假设文件在当前用户的 Downloads 目录:

sudo tar -zxvf ~/Downloads/OpenJDK13U-jdk_x64_linux_hotspot_13.0.2_8.tar.gz -C /opt/java

解压后会得到一个类似jdk-13.0.2+8的目录。为了后续配置方便,我通常会把它重命名成更简洁的名字:

sudo mv /opt/java/jdk-13.0.2+8 /opt/java/jdk-13.0.2

这样最终路径就是/opt/java/jdk-13.0.2,里面bin/java、bin/javac都在。验证一下:

/opt/java/jdk-13.0.2/bin/java -version

如果输出openjdk version "13.0.2"就说明包没问题。这一步很关键,先确认二进制能跑,再去配环境变量,否则后面出问题你分不清是包的问题还是配置的问题。

3.2 环境变量的三种配置方式与取舍

配置JAVA_HOME和PATH有三种常见做法,各有适用场景。

第一种是改/etc/profile,对所有用户生效。适合这台机器就是专门跑这个 JDK 的服务器。缺点是每次改完要source /etc/profile或者重新登录,而且所有用户都被强制用同一个版本。

第二种是在/etc/profile.d/下新建一个jdk13.sh脚本。这其实比直接改/etc/profile更规范,因为它是模块化的,卸载时删掉文件即可,不会污染主配置文件。内容如下:

export JAVA_HOME=/opt/java/jdk-13.0.2 export PATH=$JAVA_HOME/bin:$PATH

然后sudo chmod +x /etc/profile.d/jdk13.sh,重新登录后生效。

第三种是只改当前用户的~/.bashrc或~/.zshrc。这是我最推荐给开发机的做法,因为不影响系统其他用户,也不会和系统自带的 JDK 打架。在文件末尾追加:

export JAVA_HOME=/opt/java/jdk-13.0.2 export PATH=$JAVA_HOME/bin:$PATH

然后source ~/.bashrc。注意PATH里$JAVA_HOME/bin要放在前面,否则系统里如果已经有/usr/bin/java,会被优先命中。

3.3 验证配置是否真正生效

配完之后别急着写代码,先做三层验证。第一层,echo $JAVA_HOME看输出是不是/opt/java/jdk-13.0.2。第二层,which java看路径是不是指向/opt/java/jdk-13.0.2/bin/java。第三层,java -version和javac -version都要输出 13.0.2。

这里有个常见陷阱:java -version正常,但javac -version报找不到命令。这通常是因为PATH只加了$JAVA_HOME/bin但JAVA_HOME本身写错了,或者你装的是 JRE 而不是 JDK。确认/opt/java/jdk-13.0.2/bin下确实有javac文件。

还有一个更隐蔽的问题:如果你之前用apt装过其他 JDK,update-alternatives可能仍然把/usr/bin/java指向旧版本。即使你PATH配对了,某些通过绝对路径调用/usr/bin/java的脚本还是会用错版本。检查方法:

ls -l /usr/bin/java

如果它指向/etc/alternatives/java,而后者又指向别的 JDK,那就要决定是保留还是调整。我的做法是:手动安装的 JDK 不注册到update-alternatives,完全靠PATH控制,这样最可控。

4. 多版本共存时如何让 13.0.2 该出场时才出场

4.1 update-alternatives 机制的利与弊

update-alternatives是 Debian 系管理多版本命令的通用机制。它维护一个符号链接链:/usr/bin/java→/etc/alternatives/java→ 实际 JDK 路径。通过sudo update-alternatives --config java可以交互式切换。

它的好处是系统级统一,所有用户、所有终端都跟着变。坏处也在这里:你切到 13.0.2 之后,另一个需要 JDK 8 的项目就崩了。而且手动安装的 JDK 要注册进去,得用--install参数,命令比较长:

sudo update-alternatives --install /usr/bin/java java /opt/java/jdk-13.0.2/bin/java 1302 sudo update-alternatives --install /usr/bin/javac javac /opt/java/jdk-13.0.2/bin/javac 1302

后面的1302是优先级,数字越大越优先。注册完再--config切换。这套机制适合"一台机器主要用一个版本,偶尔切一下"的场景。

4.2 用 shell 函数做项目级版本切换

如果你的日常是在多个 JDK 版本之间反复横跳,update-alternatives就太重了。更轻量的做法是在~/.bashrc里定义几个函数,比如:

use_jdk13() { export JAVA_HOME=/opt/java/jdk-13.0.2 export PATH=$JAVA_HOME/bin:$PATH } use_jdk8() { export JAVA_HOME=/opt/java/jdk-1.8.0 export PATH=$JAVA_HOME/bin:$PATH }

这样在终端里敲use_jdk13就切到 13,敲use_jdk8就切到 8。缺点是只对当前终端会话有效,新开终端又回到默认。但对于"这个终端专门跑这个项目"的工作方式来说,反而更安全,不会误伤其他窗口。

4.3 项目内锁定版本的实践

更彻底的做法是在项目根目录放一个.envrc或者脚本,进入目录时自动切换。如果团队用 direnv,可以在.envrc里写:

export JAVA_HOME=/opt/java/jdk-13.0.2 export PATH=$JAVA_HOME/bin:$PATH

这样cd进项目目录,JDK 自动变成 13.0.2,cd出去又恢复。对于需要精确版本的老项目,这种方式能避免"我本地明明是 13,怎么 CI 上跑的是 11"这类扯皮。

需要提醒的是,Maven、Gradle 这类构建工具会读取JAVA_HOME,所以只要JAVA_HOME切对了,构建时用的就是对应版本。但 IDE(比如 IntelliJ IDEA)有自己的 JDK 配置,不会跟着 shell 走,需要在 IDE 的 Project Structure 里单独指定/opt/java/jdk-13.0.2。

5. 安装后必做的几项检查与常见报错处理

5.1 编码与字体相关的隐性坑

JDK 13 在 Ubuntu 上跑起来后,如果涉及中文输出,可能会遇到乱码。这通常不是 JDK 的问题,而是系统 locale 没配好。检查:

locale

如果LANG是空的或者POSIX,Java 默认会用 ASCII 编码处理文件,中文就乱了。解决办法是安装中文语言包并设置 locale:

sudo apt install language-pack-zh-hans sudo update-locale LANG=zh_CN.UTF-8

重新登录后locale应该显示zh_CN.UTF-8。另一个办法是在启动 Java 时显式指定-Dfile.encoding=UTF-8,但这属于治标,系统级配好更省心。

5.2 内存与 ulimit 限制导致的启动失败

有些项目启动时 JVM 会申请较大堆内存,如果系统ulimit限制太严,会报 "Cannot allocate memory" 或 "There is insufficient memory for the Java Runtime Environment"。查看当前限制:

ulimit -a

重点关注max memory size和virtual memory。如果是通过 systemd 管理的服务,还要看 service 文件里有没有LimitAS、LimitMEMLOCK之类的限制。临时放开可以用ulimit -v unlimited,但更规范的是在 systemd 配置里调整。

5.3 证书与 HTTPS 请求的信任问题

JDK 13.0.2 自带的cacerts是 2020 年初的,如果项目要访问一些较新的 HTTPS 服务,可能会遇到证书链验证失败。表现是javax.net.ssl.SSLHandshakeException。解决办法是更新cacerts,或者把目标站点的根证书导入:

sudo /opt/java/jdk-13.0.2/bin/keytool -importcert -alias myserver -keystore /opt/java/jdk-13.0.2/lib/security/cacerts -file /path/to/cert.pem

默认密码是changeit。导入前建议先备份原cacerts文件,改坏了还能还原。

5.4 常见报错速查表

报错信息可能原因处理方向
java: command not foundPATH 未包含 JDK bin 目录检查JAVA_HOME与PATH配置
Error: could not open ...文件权限不足确认解压目录属主与读权限
UnsupportedClassVersionError编译与运行版本不一致统一javac与java来源
No such file or directory执行 java 时架构不匹配或动态库缺失确认下载包架构,安装 libc 依赖
Could not reserve enough space内存或 ulimit 限制调整堆参数或系统限制

这张表里的每一条我都在实际环境里遇到过,尤其是UnsupportedClassVersionError,十有八九是javac和java指向了不同 JDK。用which -a java javac可以列出所有候选,一眼就能看出问题。

6. 把 JDK 13.0.2 用稳的几个个人习惯

装好只是开始,用稳才是目的。我自己的习惯是:第一,永远保留一份原始 tar.gz 在/opt/java/archives下,哪天目录被误删或者升级搞坏了,重新解压就能恢复,不用再去网上找归档包。第二,在~/.bashrc里把默认 JDK 设成项目最常用的那个版本,其他版本用函数临时切,避免每次开终端都要手动选。第三,定期用java -XshowSettings:properties -version 2>&1 | grep java.home确认当前实际使用的 JDK 路径,这个命令比java -version更直接,能看出 JVM 到底从哪个目录加载的。

还有一点值得说:JDK 13.0.2 作为非 LTS 版本,安全补丁早就停止了。如果这台机器要长期跑对外服务,建议尽早规划升级到 LTS 版本(比如 17 或 21)。但如果是内网开发、教学演示、或者维护历史项目,13.0.2 继续用着也没问题,只要清楚它的边界在哪里。我自己的做法是把它隔离在特定项目目录和特定终端会话里,不设成系统默认,这样既满足了项目需求,又不会让整台机器的 Java 环境变得不可控。

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

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

立即咨询