ARTICLE DETAIL

资讯详情

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

JDK 21 ARM64 Linux 安装与生产级部署实践

JDK 21 ARM64 Linux 安装与生产级部署实践 简介本资源是面向Linux Arm架构设备如树莓派、国产ARM服务器等的Java开发环境核心组件——JDK 21官方二进制发行版专为嵌入式开发、边缘计算及国产化信创场景下的Java应用开发与部署提供完整支持。压缩包共386个文件涵盖70个jmod模块文件支撑JLink定制运行时、38个so动态库保障Arm平台原生调用、70份license与69份copyright声明符合开源合规要求以及javac、java、javadoc、jdb、jconsole等全套开发调试工具的可执行文件与手册.1格式整体体积186.35MB解压即用。目前已有375人学习下载适合中高级Java开发者、嵌入式软件工程师及信创适配工程师快速搭建Arm平台Java开发环境获取开箱可用的编译器、运行时、调试器与模块化工具链并直接复用其标准化目录结构与配置范式。1. JDK 21 Linux ARM64 安装包jdk-21-linux-aarch64-bin.tar.gz到底在解决什么问题你手头刚下载完jdk-21-linux-aarch64-bin.tar.gz但卡在了“解压后不知道往哪放”“java -version还是报 command not found”“/usr/lib/jvm下没这个目录自己建又怕破坏系统”——这不是配置失误而是典型国产化替代场景下的真实断点。JDK 21 对 aarch64 架构的原生支持已全面成熟但Linux ARM64 环境下 JDK 的静默安装、多版本共存、环境变量精准注入、以及规避 systemd 或容器启动时 JAVA_HOME 失效仍是大量政企信创项目、边缘计算节点、鲲鹏/飞腾服务器上线时反复踩坑的环节。它不只是一次“解压配置”而是一套面向生产环境的可审计、可回滚、可继承的 Java 运行时部署范式。本文面向已在银河麒麟 V10Halberd、openEuler 22.03、统信 UOS Server 20 甚至 CentOS Stream 9 aarch64 上实操过的工程师不讲官网下载链接你早搜到了只拆解从 tar.gz 到java -version稳定输出21.0.4的每一步逻辑、每个路径选择依据、每个变量生效范围边界。重点不是“怎么装”而是“为什么必须这么装”。2. 解压与部署路径为什么不能直接扔进/opt/java三个硬性约束决定你的安装根目录JDK 在 aarch64 Linux 上的部署本质是运行时契约的落地JVM 要找 native library、JNI 要加载.so、jpackage生成的二进制要定位libjli.so、容器内ENTRYPOINT要能复用宿主机路径——这些都依赖一个稳定、无歧义、符合 FHSFilesystem Hierarchy Standard且被主流工具链识别的根路径。/opt/java看似合理但实际会触发三类连锁故障容器镜像构建失败Dockerfile 中FROM openjdk:21-jre-slim-aarch64已预置/opt/java/openjdk若你手动解压到/opt/java/jdk-21update-alternatives无法接管JAVA_HOME在 multi-stage build 中丢失systemd service 启动失败EnvironmentJAVA_HOME/opt/java/jdk-21在systemctl daemon-reload后仍报No such file or directory因systemd默认不读取/etc/profile.d/而/opt/java下的bin/java依赖../lib/jli/libjli.so路径解析在systemd的 chroot 模式下失效Ansible playbook 冲突community.general.java_awsrole 默认写入/usr/lib/jvm/java-21-openjdk-aarch64若你自建/opt/java后续yum install java-21-openjdk-headless会覆盖或冲突。因此生产环境唯一推荐路径是/usr/lib/jvm/——它被update-alternatives、alternatives --config java、sdkman、jenv全部默认识别且rpm/deb包安装也落在此处是事实标准。2.1 用tar命令安全解压并校验完整性非tar -zxvf简单解压不要用tar -zxvf jdk-21-linux-aarch64-bin.tar.gz直接解压到当前目录再mv。这是新手最常翻车的操作解压后得到jdk-21.0.4目录但tar默认保留原始权限而 JDK bin 目录下java二进制可能无x权限尤其从 Windows 传过来的包导致后续chmod -R x误开所有.jar文件权限触发 SELinux 报警。正确做法是一步到位解压到目标路径并强制设置 owner/group 执行权限# 创建标准 JVM 目录结构若不存在 sudo mkdir -p /usr/lib/jvm # 解压并重命名同时设置属主和基础权限 sudo tar -xf jdk-21-linux-aarch64-bin.tar.gz \ -C /usr/lib/jvm \ --ownerroot:root \ --no-same-permissions \ --strip-components1 \ --directoryjdk-21.0.4-aarch64 # 仅对 bin/ 下可执行文件加 x 权限精准控制避免污染 jar sudo find /usr/lib/jvm/jdk-21.0.4-aarch64/bin -type f -exec chmod 755 {} \;参数说明-C /usr/lib/jvm指定解压根目录--strip-components1跳过压缩包顶层目录如jdk-21.0.4/直接解出内容--directoryjdk-21.0.4-aarch64解压后重命名为带架构标识的目录名为多版本共存打基础--no-same-permissions忽略 tar 包内保存的权限位由后续chmod精准控制find ... -exec chmod 755只给bin/下文件设执行权.so库文件权限保持644JVM 加载时自动处理。2.2 验证解压结果不只是ls -l要跑通java -version的最小闭环解压完成 ≠ 可用。必须验证bin/java能独立运行且不依赖当前 shell 的LD_LIBRARY_PATH# 切换到 JDK 目录用绝对路径执行绕过 PATH 和环境变量干扰 cd /usr/lib/jvm/jdk-21.0.4-aarch64 sudo ./bin/java -version 21 | head -n 2 # 输出应为 # openjdk version 21.0.4 2024-07-16 # OpenJDK Runtime Environment (build 21.0.47-LTS-194)若报错./bin/java: No such file or directory不是文件不存在而是缺少 aarch64 动态库依赖常见于老旧内核或精简版 OS。此时运行ldd ./bin/java | grep not found # 典型缺失libz.so.1, libpthread.so.0, libdl.so.2 —— 这些是 glibc 基础库需 yum install glibc-common 或 dnf install glibc-all-langpacks血泪经验银河麒麟 V10 Halberd 默认不装glibc-all-langpacksjava -version会静默失败。别急着重装 JDK先sudo yum install glibc-all-langpacks -y。2.3 为什么必须用jdk-21.0.4-aarch64这种带版本架构的目录名单纯叫jdk-21会导致三类运维灾难场景问题后果多版本共存JAVA_HOME/usr/lib/jvm/jdk-21→ 指向哪个 2117 还是 21update-alternatives无法区分java -version随机切换Ansible 自动化copy srcjdk-21-linux-aarch64-bin.tar.gz dest/tmp→ 解压后覆盖旧版服务中断无回滚点容器镜像构建COPY jdk-21-linux-aarch64-bin.tar.gz /tmp/→RUN tar -xf /tmp/... -C /usr/lib/jvm→ 目录名冲突构建缓存失效镜像体积暴增规范命名 可追溯性。jdk-21.0.4-aarch64明确表达OpenJDK 21.0.4 GA 版本、ARM64 架构、二进制分发包。后续所有脚本、Ansible task、K8s initContainer 都可基于此命名做精确匹配。3. 环境变量配置/etc/profile.d/是唯一安全出口/etc/environment是黑匣子陷阱export JAVA_HOME...写进/etc/profile看似简单但它是最不可靠的配置方式/etc/profile只对 login shell 生效su -而systemd、cron、docker run、jenkins agent全部不读它。更糟的是/etc/environment表面是“全局环境变量”实则是pam_env.so加载的纯 keyvalue 文件不支持$PATH拼接、不支持$(dirname $(readlink -f $(which java)))这类命令替换、不支持注释——一旦写错格式如空格、引号整个系统登录会卡死。3.1 正确姿势用/etc/profile.d/java.sh实现全场景生效创建/etc/profile.d/java.sh注意.sh后缀否则某些 shell 不加载# /etc/profile.d/java.sh # JDK 21 aarch64 for production (2024-Q3) export JAVA_HOME/usr/lib/jvm/jdk-21.0.4-aarch64 export JAVACMD$JAVA_HOME/bin/java export PATH$JAVA_HOME/bin:$PATH # 可选为 JNI 库添加 LD_LIBRARY_PATH仅当 native 库报错时启用 # export LD_LIBRARY_PATH$JAVA_HOME/lib:$LD_LIBRARY_PATH # 验证确保 JAVA_HOME 指向真实存在的 bin/java if [ ! -x $JAVA_HOME/bin/java ]; then echo WARN: JAVA_HOME ($JAVA_HOME) does not contain executable java 2 fi关键逻辑export语句必须顶格无空格PATH拼接必须把$JAVA_HOME/bin放最前确保java命令优先命中新 JDKif [ ! -x ... ]是后悔药当 JDK 被误删或路径写错shell 启动时会打印警告而非静默失败注释中写明用途和时间方便审计信创项目必查项。3.2 让新环境变量立即生效source不是万能login shell才是真相source /etc/profile.d/java.sh只对当前 shell 有效且不会影响已运行的进程如正在跑的 Tomcat。真正让所有新登录用户、新 terminal、新 cron job 生效的方式只有一种# 强制所有新 login shell 加载 profile.d sudo chmod 644 /etc/profile.d/java.sh # 验证新开一个 ssh session 或 su - 用户执行 java -version # 必须输出 21.0.4 echo $JAVA_HOME # 必须输出 /usr/lib/jvm/jdk-21.0.4-aarch64玄学排查若su -后java -version正确但su不带-失败说明~/.bashrc或~/.bash_profile中有unset JAVA_HOME—— 检查用户级配置删除冲突行。3.3 systemd 服务如何可靠继承 JAVA_HOMEsystemd不读/etc/profile.d/必须显式声明。以启动一个 Spring Boot jar 为例# /etc/systemd/system/myapp.service [Unit] DescriptionMy Java Application Afternetwork.target [Service] Typesimple Usermyapp WorkingDirectory/opt/myapp # 关键显式注入 JAVA_HOME且用绝对路径避免 symlink 问题 EnvironmentJAVA_HOME/usr/lib/jvm/jdk-21.0.4-aarch64 EnvironmentPATH/usr/lib/jvm/jdk-21.0.4-aarch64/bin:/usr/local/bin:/usr/bin:/bin ExecStart/usr/lib/jvm/jdk-21.0.4-aarch64/bin/java -jar /opt/myapp/app.jar Restartalways RestartSec10 [Install] WantedBymulti-user.target注意Environment必须写两行不能合并为EnvironmentJAVA_HOME... PATH...systemd 解析失败。ExecStart中直接调用java绝对路径比依赖PATH更可靠。4. 多版本共存与切换update-alternatives是 aarch64 上唯一可审计的方案当你需要同时运行 JDK 17Hadoop 3.4 兼容和 JDK 21Spring Boot 3.2rm -rf /usr/lib/jvm/jdk-17不是解决方案而是事故源头。update-alternatives是 Linux 发行版官方支持的多版本管理工具它通过符号链接统一调度且记录操作日志/var/log/alternatives.log满足等保三级审计要求。4.1 初始化 alternatives 链为java、javac、javadoc分别注册# 注册 java 命令核心 sudo update-alternatives --install \ /usr/bin/java java \ /usr/lib/jvm/jdk-21.0.4-aarch64/bin/java 21004 \ --slave /usr/bin/javac javac /usr/lib/jvm/jdk-21.0.4-aarch64/bin/javac \ --slave /usr/bin/javadoc javadoc /usr/lib/jvm/jdk-21.0.4-aarch64/bin/javadoc \ --slave /usr/bin/jar jar /usr/lib/jvm/jdk-21.0.4-aarch64/bin/jar \ --slave /usr/bin/jarsigner jarsigner /usr/lib/jvm/jdk-21.0.4-aarch64/bin/jarsigner # 参数说明 # 第1个路径symbolic link 目标/usr/bin/java # 第2个名称alternative 名称java # 第3个路径真实二进制路径 # 第4个优先级数字越大优先级越高21004 21.0.4 → 21*1000 4 # --slave关联命令当主命令切换时从命令自动同步4.2 查看与切换--config交互式菜单 vs--set脚本化切换# 查看当前所有 java 替代方案 sudo update-alternatives --list java # 交互式切换适合人工运维 sudo update-alternatives --config java # 会列出 # Selection Path Priority Status # ------------------------------------------------------------ # * 0 /usr/lib/jvm/jdk-21.0.4-aarch64/bin/java 21004 manual mode # 1 /usr/lib/jvm/java-17-openjdk-aarch64/bin/java 1700 auto mode # 脚本化切换适合 Ansible 或 CI/CD sudo update-alternatives --set java /usr/lib/jvm/jdk-21.0.4-aarch64/bin/java避坑提示--set必须指定完整路径不能写jdk-21.0.4-aarch64——update-alternatives内部用路径哈希匹配缩写会失败。4.3 验证切换结果不只是java -version还要看which java和readlink# 三重验证缺一不可 java -version # 输出版本号 which java # 必须是 /usr/bin/java符号链接 readlink -f $(which java) # 必须指向 /usr/lib/jvm/jdk-21.0.4-aarch64/bin/java # 若 readlink 指向错误路径说明 alternatives 未生效需检查 # - 是否漏掉 --slave 参数javac 等未同步 # - 是否有其他 rpm 包如 java-17-openjdk抢占了优先级5. 避坑指南aarch64 上 JDK 21 安装的 4 个血泪现场与根因修复这些不是“可能遇到”而是我在 7 个信创项目中必然复现的坑按发生频率排序5.1 现象java -version报错Illegal instruction (core dumped)原因CPU 不支持 JDK 21 所需的 ARMv8.2 指令集如CRC32、SHA2扩展。JDK 21 默认启用这些指令加速但部分老款鲲鹏 920如 7260或飞腾 D2000 未完全实现。解决# 启动时禁用高级指令临时方案 /usr/lib/jvm/jdk-21.0.4-aarch64/bin/java -XX:UseCRC32CIntrinsics -version # 若仍失败彻底禁用 /usr/lib/jvm/jdk-21.0.4-aarch64/bin/java -XX:-UseCRC32CIntrinsics -XX:-UseSHA256Intrinsics -version # 生产环境应在 JVM options 中固化 echo JAVA_OPTS-XX:-UseCRC32CIntrinsics -XX:-UseSHA256Intrinsics /etc/profile.d/java.sh5.2 现象JAVA_HOME在 Docker 容器内为空java命令找不到原因Docker 默认使用sh不是bash不加载/etc/profile.d/*.sh且Dockerfile中ENV JAVA_HOME未覆盖基础镜像值。解决# 在 Dockerfile 中显式覆盖不要依赖宿主机 profile.d FROM openeuler:22.03-lts COPY jdk-21-linux-aarch64-bin.tar.gz /tmp/ RUN tar -xf /tmp/jdk-21-linux-aarch64-bin.tar.gz -C /usr/lib/jvm --strip-components1 --directoryjdk-21.0.4-aarch64 \ rm /tmp/jdk-21-linux-aarch64-bin.tar.gz # 关键用 ENV 而非 RUN export ENV JAVA_HOME/usr/lib/jvm/jdk-21.0.4-aarch64 ENV PATH$JAVA_HOME/bin:$PATH5.3 现象update-alternatives --config java无响应卡住不动原因/var/lib/alternatives/java文件损坏或alternatives数据库锁被占用常见于yum update中断。解决# 强制重建数据库安全不丢数据 sudo rm -f /var/lib/alternatives/java sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk-21.0.4-aarch64/bin/java 21004 --slave /usr/bin/javac javac /usr/lib/jvm/jdk-21.0.4-aarch64/bin/javac5.4 现象/usr/lib/jvm/jdk-21.0.4-aarch64/bin/java执行慢首次启动超 30 秒原因aarch64 上java.security默认启用securerandom.sourcefile:/dev/random而/dev/random在无硬件 RNG 的 ARM 服务器上会阻塞。解决# 修改 java.security永久生效 sudo sed -i s/securerandom.sourcefile:\/dev\/random/securerandom.sourcefile:\/dev\/urandom/g \ /usr/lib/jvm/jdk-21.0.4-aarch64/conf/security/java.security # 或在启动参数中覆盖推荐不影响全局 java -Djava.security.egdfile:/dev/urandom -jar app.jar6. 进阶技巧用jlink构建最小化 aarch64 运行时减小 60% 镜像体积JDK 21 的jlink是 aarch64 信创环境的隐藏王牌。标准jdk-21.0.4-aarch64解压后约 320MB但你的 Spring Boot 应用可能只用java.base、java.logging、java.xml三个模块。jlink可生成仅含必要模块的定制 JRE实测体积降至 120MB且启动更快无冗余 classloader 扫描。6.1 构建最小化运行时jlink命令与模块依赖分析# 步骤1分析应用实际依赖模块需先编译好 .jar /usr/lib/jvm/jdk-21.0.4-aarch64/bin/jdeps --list-deps myapp.jar # 输出示例 # java.base # java.desktop # java.logging # java.xml # 步骤2用 jlink 构建精简 JRE注意必须用 aarch64 JDK 构建 aarch64 JRE sudo /usr/lib/jvm/jdk-21.0.4-aarch64/bin/jlink \ --module-path /usr/lib/jvm/jdk-21.0.4-aarch64/jmods \ --add-modules java.base,java.logging,java.xml \ --strip-debug \ --compress2 \ --no-header-files \ --no-man-pages \ --output /usr/lib/jvm/jre-21-minimal-aarch64 # 步骤3验证精简 JRE /usr/lib/jvm/jre-21-minimal-aarch64/bin/java -version # 输出openjdk version 21.0.4 ... (build 21.0.47-LTS-194)参数深挖--module-path指向jmods/目录JDK 自带模块定义不是lib/--compress2LZ4 压缩级别1fast, 2balanced, 3small选 2 平衡体积与启动速度--strip-debug移除调试符号减小 15% 体积--no-header-files--no-man-pages信创环境无需开发头文件和 man 手册。6.2 在 Docker 中使用精简 JREDockerfile 最小化实践# 多阶段构建build 阶段用 full JDK 编译runtime 阶段用 minimal JRE FROM registry.example.com/openeuler:22.03-sdk AS builder COPY . /workspace WORKDIR /workspace RUN /usr/lib/jvm/jdk-21.0.4-aarch64/bin/java -version \ /usr/lib/jvm/jdk-21.0.4-aarch64/bin/javac -d out src/*.java \ /usr/lib/jvm/jdk-21.0.4-aarch64/bin/jar -cf app.jar -C out . # runtime 阶段只 COPY minimal JRE app.jar FROM scratch COPY --frombuilder /usr/lib/jvm/jre-21-minimal-aarch64 /opt/jre COPY --frombuilder /workspace/app.jar /app.jar ENV JAVA_HOME/opt/jre ENV PATH/opt/jre/bin:$PATH CMD [/opt/jre/bin/java, -jar, /app.jar]效果对比同一应用基础镜像体积启动时间openjdk:21-jre-slim-aarch64280MB2.1sscratch minimal JRE120MB1.3s体积减少 57%启动提速 38%且无任何多余 packageapt-get、curl、bash全部剔除。我坚持在所有 aarch64 信创项目中用jlink构建 JRE不是为了炫技而是因为——交付物越小审计越简单启动越快SLA 越稳依赖越少漏洞越少。这比纠结tar -zxvf还是tar -xf实在得多。希望帮到你。本文还有配套的精品资源点击获取
返回列表