news 2026/8/13 5:05:10

Ubuntu 20.04 JDK安装配置全攻略:apt、手动与SDKMAN方案详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ubuntu 20.04 JDK安装配置全攻略:apt、手动与SDKMAN方案详解

1. 项目概述:为什么在Ubuntu上配置JDK是开发者的必修课

如果你是一名Java开发者,或者正准备踏入后端、大数据、安卓开发等领域,那么“在Linux系统上配置Java开发环境”几乎是你的第一道门槛。Ubuntu 20.04 LTS作为一个长期支持版本,以其稳定性和广泛的社区支持,成为了众多开发者和服务器环境的首选。而JDK(Java Development Kit),作为Java程序运行的基石,其安装与配置的顺畅与否,直接决定了你后续的开发体验是“一路绿灯”还是“步步踩坑”。

我见过太多新手,包括几年前的我自己,在sudo apt install default-jdk之后,就以为万事大吉,结果在运行java -version时发现版本不对,或者在IDE中配置SDK时找不到路径,又或者构建工具如Maven、Gradle因为JAVA_HOME环境变量没设而报错。这些问题看似简单,但背后涉及的是对Linux包管理、环境变量作用域以及Java版本管理的理解。今天,我就以Ubuntu 20.04为例,带你彻底搞懂JDK安装的几种主流方式、它们之间的优劣,以及如何进行一次“教科书级”的配置,确保你的开发环境干净、可控且易于维护。无论你是刚接触Linux的小白,还是想优化现有工作流的老手,这篇详尽的指南都能让你有所收获。

2. 核心方案选型:apt安装、手动解压与SDKMAN的深度对比

在Ubuntu上安装JDK,远不止一条路。选择哪种方式,取决于你的具体需求:是追求极致的简便,还是需要灵活的版本切换,或是要求特定的JDK发行版。下面我们来拆解三种最常用的方案。

2.1 方案一:使用apt包管理器安装(适合新手及快速部署)

这是最直接的方法。Ubuntu的官方软件仓库包含OpenJDK的包。

操作与原理:

  1. 更新软件包列表:首先执行sudo apt update。这个命令并不会更新任何已安装的软件,而是刷新本地软件包索引,从配置的软件源服务器获取最新的软件包列表及其版本信息。这是确保你能安装到最新可用版本的关键第一步。
  2. 安装JDK:执行sudo apt install default-jdk。这里安装的default-jdk是一个元数据包,它会自动指向当前Ubuntu版本推荐的最新稳定版OpenJDK。例如在Ubuntu 20.04上,它通常会安装OpenJDK 11。你也可以安装特定版本,如openjdk-11-jdkopenjdk-8-jdk

优点:

  • 极其简单:两条命令搞定,无需关心下载、解压、路径。
  • 自动管理:后续可以通过apt统一更新或卸载,与系统其他软件包管理方式一致。
  • 集成度高:安装后,javajavac命令通常已自动添加到系统路径。

缺点与注意事项:

  • 版本受限:仓库中的版本可能不是最新的。例如,你可能需要JDK 17或21,但官方仓库可能只提供到11或17。
  • 发行版单一:通常只有OpenJDK,如果你需要Oracle JDK、Amazon Corretto等特定发行版,此方法不适用。
  • 安装路径分散:通过apt安装的JDK,其文件会分散在系统的多个标准目录中(如/usr/lib/jvm/),对于想集中管理多个JDK版本的用户来说不够直观。

注意:如果你需要为所有用户安装,或者是在配置生产服务器,且对JDK版本要求不苛刻,apt安装是最稳妥、最符合Linux哲学的方式。

2.2 方案二:下载归档文件手动安装(适合需要特定版本或发行版)

这是最灵活、最通用的方法,适用于任何Linux发行版。你可以从各JDK提供商官网下载所需的.tar.gz归档文件。

操作流程与深层逻辑:

  1. 选择与下载:访问如 Adoptium (推荐,提供高性能的Eclipse Temurin JDK)、 Oracle官网 、 Amazon Corretto 等,选择Linux x64的.tar.gz包。我强烈推荐Adoptium/Temurin,它完全开源、免费,且性能优异。
  2. 规划安装目录:Linux有一个约定俗成的目录/usr/lib/jvm/,专门用于存放Java虚拟机。手动安装时,将JDK解压到此目录下,可以保持系统整洁,也与其他管理工具(如update-alternatives)的预期一致。执行sudo mkdir -p /usr/lib/jvm创建目录(如果不存在)。
  3. 解压与放置:使用tar命令解压下载的包到目标目录。例如:sudo tar -xzf jdk-21_linux-x64_bin.tar.gz -C /usr/lib/jvm/。这里的-C参数指定了解压目标目录。
  4. 核心配置:手动安装后,系统并不知道这个新Java的存在。你需要通过设置环境变量来告诉它。

优点:

  • 版本与发行版完全自主:可以安装任何版本、任何供应商的JDK。
  • 环境纯净独立:所有文件集中在自己的目录下,删除时直接移除整个目录即可,不会遗留分散的文件。
  • 多版本并行管理基础:为使用工具管理多个版本打下了基础。

缺点:

  • 步骤繁琐:需要手动下载、解压、配置环境变量。
  • 更新麻烦:升级新版本需要重复此过程,并手动更新环境变量指向。

2.3 方案三:使用SDKMAN进行安装与管理(适合开发者,强烈推荐)

如果你是一名开发者,需要在同一台机器上频繁切换不同项目所需的JDK版本(比如老项目用JDK 8,新项目用JDK 21),那么SDKMAN是你的终极武器。它是一个用于管理多个软件开发工具包(SDK)版本的工具,支持Java、Groovy、Scala等。

工作原理:SDKMAN本质上是一个命令行工具,它维护了一个丰富的软件包仓库。当你通过它安装JDK时,它会自动从镜像站点下载指定的发行版,解压到它自己的管理目录(~/.sdkman/candidates/java/下),并自动配置当前Shell的环境变量。

优点:

  • 一键安装与切换:命令如sdk install java 21.0.2-tem即可安装特定版本,sdk use java 11.0.22-tem可快速切换当前Shell的版本。
  • 多版本无缝共存:所有版本井然有序地存放在一起,互不干扰。
  • 支持众多发行版:可以轻松安装Temurin、Corretto、Oracle、Zulu等几乎所有主流JDK发行版。
  • 自动配置:安装后即用,无需手动设置JAVA_HOMEPATH

缺点:

  • 需要额外安装工具:需先安装SDKMAN本身。
  • 主要面向用户级:默认安装到用户主目录,更适合开发环境。如需配置系统级的全局JDK,仍需结合其他方法。

如何选择?

  • 初学者/快速搭建一次性环境:使用方案一(apt)
  • 服务器生产环境,使用稳定版OpenJDK:使用**方案一(apt)方案二(手动)**指定稳定版本。
  • 开发者工作站,需要多版本切换:毫不犹豫地选择方案三(SDKMAN)
  • 需要特定非OpenJDK发行版(如Oracle JDK):使用方案二(手动)

接下来,我将以**方案二(手动安装)**为例,进行最详细的演示,因为它涵盖了从下载、安装到配置的全流程,理解了它,其他方案也就触类旁通。最后,我会补充SDKMAN的快速上手指南。

3. 手动安装JDK 21与系统级环境变量配置全解析

我们以从Adoptium下载最新的JDK 21 LTS版本为例,演示手动安装的完整过程。之所以选择JDK 21,因为它是最新的长期支持版本,代表了未来的方向。

3.1 步骤一:下载与校验

首先,打开终端。

  1. 前往下载页面:你可以通过浏览器访问Adoptium网站下载,但作为开发者,在终端里用wgetcurl直接下载更酷。我们先找到下载链接。通常,Adoptium的下载链接有固定模式。
  2. 使用wget下载:执行以下命令。请注意,实际的下载链接可能会随版本更新而变化,建议去官网核对。
    wget https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21%2B35/OpenJDK21U-jdk_x64_linux_hotspot_21_35.tar.gz
    这里解释一下参数:-21%2B35中的%2B是URL编码的加号+,代表构建号。x64_linux_hotspot指64位Linux系统,HotSpot虚拟机。
  3. (可选)校验文件完整性:对于生产环境,校验下载文件的SHA256散列值是很好的习惯。你可以在下载页面找到校验和。使用sha256sum命令:
    sha256sum OpenJDK21U-jdk_x64_linux_hotspot_21_35.tar.gz
    将输出的字符串与官网提供的进行比对,完全一致则说明文件下载无误。

3.2 步骤二:解压与部署到系统目录

现在,我们将这个归档文件解压到系统标准的JVM目录。

  1. 创建目标目录(如果不存在):前面提到,/usr/lib/jvm是惯例位置。
    sudo mkdir -p /usr/lib/jvm
    -p参数确保如果目录不存在则创建,且不会因为父目录不存在而报错。
  2. 解压归档文件
    sudo tar -xzf OpenJDK21U-jdk_x64_linux_hotspot_21_35.tar.gz -C /usr/lib/jvm/
    • -x:解压。
    • -z:通过gzip过滤,因为文件是.tar.gz格式。
    • -f:指定归档文件名。
    • -C:改变解压到的目录。这是关键,确保文件不会解压到当前凌乱的目录下。
  3. 验证解压结果:解压后,/usr/lib/jvm目录下会多出一个以JDK版本命名的文件夹,例如jdk-21+35。我们可以查看一下:
    ls -lh /usr/lib/jvm/
    你应该能看到类似jdk-21+35的目录。这个目录的完整路径就是你的JAVA安装路径,记下它,稍后配置环境变量需要。我们假设完整路径是/usr/lib/jvm/jdk-21+35

3.3 步骤三:配置全局环境变量(关键步骤)

这是核心环节。我们需要设置两个关键环境变量:JAVA_HOMEPATH

为什么是JAVA_HOME许多Java应用和工具(如Tomcat, Maven, Gradle, IDE)都依赖JAVA_HOME环境变量来定位Java安装位置。它指向的是JDK的根目录。

为什么修改PATHPATH变量告诉系统,当你在终端输入一个命令(如javajavac)时,应该去哪些目录下寻找这个命令的可执行文件。我们需要将JDK的bin目录($JAVA_HOME/bin)加入PATH,这样就能在任意位置直接使用javajavac等命令。

配置方法选择: 在Linux中,环境变量可以在不同层级设置:

  • 临时生效:在当前终端会话中,直接export JAVA_HOME=...,关闭终端即失效。
  • 用户级永久生效:将配置写入用户家目录的shell配置文件(如~/.bashrc~/.zshrc),只对该用户生效。
  • 系统级全局生效:将配置写入/etc/profile.d/目录下的脚本,对所有用户生效。

这里我们采用系统级全局配置,因为它更通用,尤其适合服务器环境。

  1. 创建环境变量脚本:在/etc/profile.d/目录下创建一个新的shell脚本。这个目录下的脚本会在所有用户登录时被自动加载。

    sudo nano /etc/profile.d/jdk21.sh

    我习惯用nano编辑器,你也可以用vim

  2. 编写脚本内容:在打开的编辑器中,输入以下内容:

    #!/bin/bash # Set JAVA_HOME to our JDK 21 installation export JAVA_HOME=/usr/lib/jvm/jdk-21+35 # Add JAVA_HOME/bin to PATH export PATH=$JAVA_HOME/bin:$PATH

    重要解释

    • export JAVA_HOME=...:设置JAVA_HOME变量,值必须是你刚才解压的JDK目录的绝对路径
    • export PATH=$JAVA_HOME/bin:$PATH:将$JAVA_HOME/bin添加到PATH变量的最前面:是路径分隔符)。放在前面意味着系统会优先使用我们手动安装的JDK命令,而不是系统可能自带的旧版本。
  3. 保存并退出:在nano中,按Ctrl+O写入,回车确认,再按Ctrl+X退出。

  4. 使配置立即生效(对于当前终端)/etc/profile.d/中的脚本通常需要重新登录或启动新的Shell会话才能生效。我们可以使用source命令直接加载它:

    source /etc/profile.d/jdk21.sh

3.4 步骤四:验证安装与配置

现在,让我们检验一切是否就绪。

  1. 检查JAVA_HOME

    echo $JAVA_HOME

    终端应该输出/usr/lib/jvm/jdk-21+35

  2. 检查Java版本

    java -version

    你应该看到类似下面的输出,确认是JDK 21:

    openjdk version "21.0.2" 2024-01-16 OpenJDK Runtime Environment Temurin-21.0.2+13 (build 21.0.2+13) OpenJDK 64-Bit Server VM Temurin-21.0.2+13 (build 21.0.2+13, mixed mode, sharing)
  3. 检查编译器版本

    javac -version

    输出应为javac 21.0.2。能成功执行javac命令,证明JDK(而不仅仅是JRE)已正确安装。

  4. 检查PATH优先级:输入which javawhich javac,它们应该指向/usr/lib/jvm/jdk-21+35/bin/下的可执行文件,而不是/usr/bin/下的其他版本。

至此,一个系统级的、全局生效的JDK 21就安装配置完成了。所有用户登录后都可以直接使用。

4. 使用SDKMAN进行多版本JDK管理实战

对于个人开发机,SDKMAN提供了无与伦比的便利性。我们来快速过一遍它的使用。

4.1 安装SDKMAN

安装过程非常简单,只需一条命令(需要curl、zip、unzip等基础工具,Ubuntu通常已预装):

curl -s "https://get.sdkman.io" | bash

安装完成后,按照终端的提示,执行:

source "$HOME/.sdkman/bin/sdkman-init.sh"

或者直接新开一个终端窗口。为了永久生效,安装脚本通常已经将初始化命令添加到了你的~/.bashrc中。

4.2 使用SDKMAN安装与管理JDK

  1. 列出所有可安装的Java版本

    sdk list java

    你会看到一个非常长的列表,展示了各个供应商(Vendor)、版本号、发行版(Dist)和状态。Identifier一列就是安装时需要用到的标识符。

  2. 安装一个特定版本:例如,安装Temurin的JDK 21:

    sdk install java 21.0.2-tem

    SDKMAN会自动下载、解压、安装,并询问你是否将其设置为默认版本。回答Y即可。

  3. 查看已安装的版本

    sdk list java | grep installed

    或者更简单地:sdk current java

  4. 切换当前Shell使用的版本:如果你安装了多个版本,可以随时切换:

    sdk use java 11.0.22-tem

    这个切换只对当前终端会话有效。非常适合在不同项目间切换。

  5. 设置全局默认版本:如果你希望新打开的终端默认使用某个版本:

    sdk default java 21.0.2-tem

SDKMAN的目录:所有通过SDKMAN安装的软件都位于~/.sdkman/candidates/目录下。每个工具(如java)的子目录里就是各个版本。环境变量JAVA_HOME会被自动设置为~/.sdkman/candidates/java/current,这是一个指向当前激活版本的符号链接。

5. 进阶配置、问题排查与最佳实践

即使安装成功,在实际开发中你仍可能遇到一些“坑”。下面是我总结的常见问题与处理技巧。

5.1 配置JAVA_HOME的替代与进阶方法

除了在/etc/profile.d/中设置,还有一些场景化配置:

  • 为特定用户设置不同版本:如果系统全局是JDK 11,但你的项目需要JDK 17,只需将export JAVA_HOME=...export PATH=...这两行写入你的~/.bashrc~/.zshrc文件末尾。用户级的配置会覆盖系统级配置。
  • 在Shell脚本中临时指定:在脚本开头显式设置JAVA_HOME,可以确保脚本运行环境独立。
    #!/bin/bash export JAVA_HOME=/path/to/your/jdk export PATH=$JAVA_HOME/bin:$PATH # ... 你的脚本逻辑

5.2 使用update-alternatives管理系统命令链接(可选但推荐)

当你手动安装了多个JDK(比如通过apt装了OpenJDK 11,又手动装了JDK 21),系统可能会有多个java命令。update-alternatives是Debian/Ubuntu系统用来管理相同功能软件(如javajavac)多个版本的命令。

配置update-alternatives

sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk-21+35/bin/java 1000 sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk-21+35/bin/javac 1000
  • --install <链接> <名称> <路径> <优先级>:在系统命令目录(/usr/bin)创建一个符号链接java,指向我们指定的JDK可执行文件。优先级数字越大,在自动模式下被选中的可能性越高。

切换版本

sudo update-alternatives --config java

执行后会列出所有已注册的Java版本,输入编号即可切换。这提供了另一种系统级的版本切换方式,与JAVA_HOME环境变量可以配合使用。

5.3 常见问题排查实录

问题1:执行java -version显示的版本不是我刚安装的。

  • 原因PATH环境变量中,旧版本Java的路径排在了新版本的前面。
  • 排查
    1. 执行echo $PATH,查看路径顺序。确保$JAVA_HOME/bin在靠前的位置。
    2. 执行which java,查看实际调用的java命令来自哪个路径。
  • 解决
    • 检查你的环境变量脚本(如jdk21.sh),确保PATH的修改是$JAVA_HOME/bin:$PATH(新路径在前)。
    • 执行source /etc/profile.d/jdk21.sh或重新打开终端。
    • 如果使用了update-alternatives,用sudo update-alternatives --config java切换。

问题2:IDE(如IntelliJ IDEA, Eclipse)找不到JDK。

  • 原因:IDE通常有自己独立的SDK配置,不一定会读取系统的JAVA_HOME
  • 解决
    • 在IDE的设置(Settings/Preferences)中,找到Build, Execution, Deployment->Build Tools->Maven/Gradle,检查JDK for importer是否设置正确。
    • 更重要的是,在Project StructurePreferences for New Projects中,手动添加你安装的JDK路径(/usr/lib/jvm/jdk-21+35)。IDE会自动识别bin目录和版本信息。

问题3:安装后,javac命令找不到(command not found)。

  • 原因:你可能只安装了JRE(Java Runtime Environment),而不是JDK。JRE只包含运行环境,没有编译器javac
  • 排查:确认你下载安装的是jdk包,而不是jre包。通过apt安装时,要安装default-jdkopenjdk-xx-jdk,而不是default-jre
  • 解决:重新安装正确的JDK包。

问题4:使用SDKMAN安装时下载速度极慢或失败。

  • 原因:网络连接问题,或默认镜像源在国外。
  • 解决:可以尝试修改SDKMAN的镜像源为国内镜像(如华为云镜像)。编辑~/.sdkman/etc/config文件,将sdkman_roxy_urlsdkman_zip_endpoint等配置指向国内镜像地址(具体地址需查询相关镜像站文档)。或者,在安装时使用手动下载后离线安装的方式。

5.4 最佳实践与心得

  1. 生产服务器优先使用LTS版本:对于线上环境,强烈建议使用长期支持(LTS)版本,如JDK 11, 17, 21。它们提供更长时间的安全更新,稳定性更有保障。非LTS版本(如18, 19, 20)仅提供6个月的支持,适合开发者尝鲜。
  2. 开发机使用SDKMAN:这能极大提升效率。为不同的项目创建.sdkmanrc文件,在项目根目录执行sdk env,即可自动切换到该项目所需的JDK(以及其他工具如Maven)版本。
  3. 明确JAVA_HOMEPATH的关系JAVA_HOME是一个“指针”,告诉应用程序Java安装在哪里。PATH是一个“寻址目录”,告诉系统在哪里可以找到可执行命令。两者通常需要配合设置。
  4. 清理旧版本:使用apt安装的JDK,可以用sudo apt remove openjdk-11-jdk卸载。手动安装的,直接删除/usr/lib/jvm/下对应的目录,并清理环境变量配置和update-alternatives中的注册项即可。保持环境整洁。
  5. 验证安装的完整性:安装后,除了java -version,最好写一个简单的HelloWorld.java程序,用javac编译,再用java运行,确保整个工具链是通的。

最后,我个人在经历了无数次环境配置后,现在的标准做法是:在个人笔记本上,一律使用SDKMAN来管理所有JDK和JVM相关工具(如Maven, Gradle, Groovy)。在云服务器或Docker容器中,如果需要固定版本,则通过下载特定发行版的.tar.gz包手动安装,并将环境变量配置写入Dockerfile或基础设施即代码(IaC)脚本中,确保环境可重现。至于简单的apt安装,除非是临时测试,否则已经很少使用了,因为它对版本的控制力太弱。希望这份超详细的指南,能帮你构建一个坚实、灵活的Java开发基础环境。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/13 5:03:17

弹性网络模型(ENM)模拟:从原理到实践,解析生物大分子动力学

1. 项目概述&#xff1a;从零开始理解ENM模拟最近在整理学习笔记&#xff0c;发现“ENM模拟”这个概念在多个技术社区和论坛的讨论热度一直不低&#xff0c;尤其是在电子设计自动化、材料科学和生物物理这些交叉领域。ENM&#xff0c;全称是Elastic Network Model&#xff0c;中…

作者头像 李华
网站建设 2026/8/13 4:56:24

51单片机核心架构、开发流程与典型应用场景深度解析

1. 从零认识51单片机&#xff1a;它到底是什么&#xff1f;如果你对电子制作、智能硬件或者嵌入式开发感兴趣&#xff0c;那么“51单片机”这个名字你肯定绕不过去。我第一次接触它&#xff0c;还是在大学实验室里&#xff0c;看着一块小小的黑色芯片&#xff0c;通过几行代码就…

作者头像 李华
网站建设 2026/8/13 4:55:41

ANCF梁单元在梯度缺陷悬臂梁大变形仿真中的应用

1. 项目背景与核心问题在工程结构分析领域&#xff0c;悬臂梁的弯曲变形研究一直是基础而重要的课题。传统有限元方法在处理大变形问题时往往面临精度下降和收敛困难等挑战。绝对节点坐标公式(ANCF)梁单元因其独特的参数化方式&#xff0c;能够准确描述梁结构的大位移和大变形行…

作者头像 李华
网站建设 2026/8/13 4:55:34

ComfyUI模型管理:解决文件名冲突的3种方案

1. ComfyUI模型管理痛点解析 当你在ComfyUI中加载了上百个模型文件后&#xff0c;突然发现工作流无法正常识别某些模型&#xff0c;或者系统提示"模型文件已存在"——这大概率遇上了文件名冲突问题。作为Stable Diffusion生态中最受欢迎的节点式UI工具&#xff0c;Co…

作者头像 李华
网站建设 2026/8/13 4:52:05

Linux与macOS系统架构识别指南:x86-64与ARM64的区分与实践

1. 项目概述&#xff1a;为什么我们需要区分系统架构&#xff1f;在软件开发和系统运维的日常工作中&#xff0c;我经常遇到一个看似简单却至关重要的问题&#xff1a;我手头的这台机器&#xff0c;到底是基于传统的 x86-64&#xff08;也常被称为 amd64&#xff09;架构&#…

作者头像 李华
网站建设 2026/8/13 4:51:53

Ubuntu 20.04下ORB-SLAM3完整安装与运行指南:从依赖编译到实战调试

1. 项目概述与核心价值在机器人、自动驾驶和增强现实这些前沿领域&#xff0c;让机器“看见”并理解自己所处的三维环境&#xff0c;是核心的底层能力。SLAM&#xff08;即时定位与地图构建&#xff09;技术就是实现这一能力的钥匙。而ORB-SLAM3&#xff0c;作为当前开源SLAM方…

作者头像 李华