1. 多个JDK版本面临的问题
-
公司大多数业务都是用Oracle JDK 8,笔者做大数据查询引擎调研时,则需要使用JDK 17
-
因此,需要在Linux服务器同时安装JDK 8和17,同时需要能智能地快速切换JDK版本,以使用不同的查询引擎需求
-
JDK 8是由公司系统运维在重装系统时帮忙安装的,JDK 17需要笔者自己安装
-
公司内网限制,笔者选择手动安装Open JDK 17,通过修改
/etc/profile
配置JAVA_HOME
export JAVA_HOME=/usr/java/jdk-17.0.5+8 # export JAVA_HOME=/usr/java/jdk1.8.0_192-amd64 export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
-
从上面的配置可以看出,当笔者需要使用JDK 8时,则更新
/etc/profile
,注释掉JDK 17的JAVA_HOME -
source /etc/profile
后,可以让JDK 8重新生效,而JDK 17被禁用 -
在笔者看来,这是一种解决方案,但笔者想知道是否还有更智能的解决方案
2. update-alternatives管理多个JDK版本
- 通过查阅大量资料后发现,大家都比较推崇通过
update-alternatives
或者alternatives
命令,实现多个JDK版本的管理
2.1 失败的实战
-
按照网上教程,首先查看Linux服务器是否拥有JDK的软链接
update-alternatives --config java
-
Linux服务器上没有JDK的软链接
-
通过如下命令创建软链接
update-alternatives --install /usr/bin/java java /usr/java/jdk1.8.0_192-amd64/bin/java 1 update-alternatives --install /usr/bin/java java /usr/java/jdk-17.0.5+8/bin/java 2
-
输入命令,查看并选择JDK版本
update-alternatives --config java
-
这里选择的是JDK 17:
-
意外的是,输入
java -version
,仍然显示JDK 8。甚至尝试将/etc/profile
中JDK相关配置都注释掉,仍然未能成功切换到JDK 17
-
最后怕影响使用,不得不删除通过
update-alternatives
创建的软链接update-alternatives --remove java /usr/java/jdk1.8.0_192-amd64/bin/java update-alternatives --remove java /usr/java/jdk-17.0.5+8/bin/java
-
参考链接:Ubuntu 系统安装多个版本的 JDK ,只参考了如何通过
update-alternatives
管理多版本JDK
2.2 失败原因猜测
-
后来查阅大量资料后发现,仍百思不得其解
-
笔者甚至基于某些成功实例的JDK是通过Linux命令安装的,大胆推测:只有通过Linux命令安装JDK,才能使用
update-alternatives
进行管理yum install java-11-openjdk -y
-
加以佐证上述猜测的成功实例:
-
不过冷静下来一想,人家还有手动安装的成功实例 😂
3. 最新后续
3.1 工作中问题带来的启发
3.1.1 新装的机器JDK使用有问题
- 系统运维最近帮忙重装系统的测试机器,无法通过
sudo -u presto
启动Presto服务 - 最开始以为是最新版本的Presto带来的影响,结果发现线上最近扩容的机器,在启动低版本的Presto服务时也存在类似问题
- 系统运维的同事帮忙排查后,发现:
-
java命令在
/etc/sudoers
中的secure_path指定的各种路径下找不到
-
想要通过sudo方式使用java命令,要求java命令必须在/etc/sudoers的secure_path指定的路径下
-
系统运维是通过shell脚本,模拟手动安装的方式,完成JDK 8安装的
# 大致步骤的shell伪代码如下 wget jdk1.8.0.tar.gz tar -zxf jdk1.8.0.tar.gz echo JAVA_HOME_CONFIG > /etc/profile.d/jdk.sh # 等价于在/etc/profile配置JAVA_HOME source /etc/profile
-
显然,上述方式安装JDK 8,java命令不会在secure_path指定的路径下
-
- 而之前的机器,之所以能通过sudo -u presto启动Presto服务,是因为在/usr/bin目录下存在java的软链接,而/usr/bin又是secure_path指定的路径路径之一
3.1.2 yum install重新安装JDK 8
-
使用另一个脚本,实质通过yum install重装了JDK 8
-
通过yum install安装的JDK 8,自动在/usr/bin目录下创建了java命令的软链接
-
并且通过
alternatives --list
,发现自动配置了java、javac等命令的alternatives软链接
-
通过sudo也能成功找到java命令
3.2 再次尝试
-
再次尝试,将/etc/profile中配置的JAVA_HOME去掉,通过
update-alternatives
创建JDK 17的java、javac命令的update-alternatives --install /usr/bin/java java /usr/java/jdk-17.0.5+8/bin/java 2 update-alternatives --install /usr/bin/javac javac /usr/java/jdk-17.0.5+8/bin/javac 2
-
创建软链接后,能通过
update-alternatives
切换JDK版本
3.3 自己最终的结论
- 要想通过alternatives命令管理多个JDK版本,最稳妥的办法:yum install安装JDK,让其自动帮忙创建软链接
- 笔者虽然在yum install安装JDK 8以后,成功创建了JDK 17的软链接,但尚未清楚其中玄机:
- 为什么之前不行,这次忽然就行?
- 是之前的尝试有问题?还是yum install安装JDK 8是个引子,触发了什么开关?