为何rpm -Uvh升级JDK11会删除其他版本?如何保留升级?
问题分析:rpm -Uvh升级JDK11时误删JDK8/17的原因与解决方案
原因分析
- RPM包的冲突/替换规则:部分JDK RPM包(尤其是非官方或Oracle的部分包)会设置
Obsoletes或Provides标签,标记自己替代所有同属jdk类别的包,导致rpm -Uvh执行升级时自动删除其他大版本的JDK。 - 包命名不规范:如果JDK RPM包的通用名称是
jdk而非带版本号的jdk-11,rpm会将所有jdk开头的包视为同一个软件的不同版本,升级时直接替换掉所有匹配的包,包括JDK8、JDK17。 - rpm升级逻辑限制:
rpm -Uvh的核心逻辑是“升级替换”,如果包的元数据声明了覆盖其他版本,就会触发删除操作,不会区分大版本差异。
可行解决方案
1. 使用带明确版本标识的RPM包
选择文件名和包名中包含完整版本号的RPM包(比如jdk-11.0.19-1.x86_64.rpm),这类包通常不会标记为替代其他大版本JDK。执行升级时指定完整包名:
rpm -Uvh jdk-11.0.19-1.x86_64.rpm
2. 禁用rpm的自动过时替换
使用--noobsoletes参数,阻止rpm处理包的Obsoletes声明,仅升级目标JDK11版本,不删除其他版本:
rpm -Uvh --noobsoletes jdk-11.0.19-1.x86_64.rpm
注意:这个参数会跳过所有过时替换逻辑,不会影响其他已安装的JDK包。
3. 改用yum/dnf升级(推荐)
yum/dnf的依赖管理比直接用rpm更智能,能精准定位目标版本升级,避免误删。在Ansible Playbook中用yum模块替代command/shell:
- name: 升级JDK11到11.0.19 yum: name: jdk-11.0.19 state: present exclude: jdk-8*,jdk-17*
或者直接用update指令指定仅升级JDK11相关包:
yum update jdk-11*
4. 手动卸载旧版再安装新版
如果升级方式容易触发冲突,先卸载旧的JDK11版本,再安装新版本,彻底避免替换逻辑:
rpm -e jdk-11.0.18-1.x86_64 rpm -ivh jdk-11.0.19-1.x86_64.rpm
对应Ansible步骤:
- name: 卸载旧版JDK11 yum: name: jdk-11.0.18 state: absent - name: 安装JDK11.0.19 yum: name: jdk-11.0.19 state: present
5. 检查并更换有问题的RPM包
先查看目标RPM包的元数据,确认是否存在不合理的替换声明:
# 查看包是否声明替代其他JDK版本 rpm -qp --obsoletes jdk-11.0.19-1.x86_64.rpm # 查看包的提供标识 rpm -qp --provides jdk-11.0.19-1.x86_64.rpm
如果输出中包含obsoletes: jdk或provides: jdk(不带版本号),说明这个包会替换所有JDK版本,建议更换为OpenJDK官方包或其他无此类声明的RPM包。
内容的提问来源于stack exchange,提问作者RealWebstar
相关产品推荐
相关产品推荐

