背景:来了一个新项目,要求是JDK17,但是手上还有一直在迭代的项目用的是JDK8,为了避免不同版本的编译问题,也不想单独再新增一个虚拟机再安装一套JDK17的环境,所以就打算在同一个虚拟机上安装两套不同的JDK版本并管理起来,需要用到哪个版本的jdk使用命令切换即可。


在Debian/Ubuntu系统上,使用update-alternatives命令来管理多个Java版本是一种很好的方法,这允许你在系统层面设置默认的Java版本,同时也便于用户在不同版本间切换,而不会影响到系统级的默认设置。下面是如何使用update-alternatives设置和切换Java版本的步骤:

一、安装JDK8

1、查看当前系统的java版本,使用java -version查看:

2、由于虚拟机上已经存在JDK17了,所以只需要再安装JDK8即可,使用如下命令进行安装:

# 更新你的包列表,确保你能够获取到最新的软件包信息
sudo apt update

# 安装OpenJDK 8的开发工具包(JDK),包括Java编译器和其他开发工具
sudo apt install openjdk-8-jdk

二、更新alternatives

1、添加Java可执行文件

       添加JDK17,将下面的/usr/local/jdk/jdk-17.0.11 路径换成自己电脑上JDK17的安装路径即可。后面的1080是优先级,默认选择优先级高的。

sudo update-alternatives --install /usr/bin/java java /usr/local/jdk/jdk-17.0.11/bin/java 1080

sudo update-alternatives --install /usr/bin/javac javac /usr/local/jdk/jdk-17.0.11/bin/javac 1080

        添加JDK8,我这边因为经常使用的是JDK1.8,所以就将优先级设置的高于JDK17的,这样就默认选择JDK1.8。将下民JDK1.8的路径换成自己的即可。

sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-8-openjdk-amd64/bin/java 1090

sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/java-8-openjdk-amd64/bin/javac 1090

2、查看已注册的Java版本

上面添加完成之后,通过如下命令查看已注册的java版本

# 查看已注册的java版本
sudo update-alternatives --display java

# 查看已注册的javac版本
sudo update-alternatives --display javac

3、设置java版本

输入如下命令,可以看到当前系统中的java版本,前面的*表示当前选择的

sudo update-alternatives --config java

上面显示的默认选择的是java8版本的,那是因为我们刚才配置的时候设置的优先级高,如果此时我想使用java17,那么输入编号3,enter即可。

4、验证java版本是否正常切换

输入java -version,验证java版本是否是上面我们设置的那样。

java -version

5、javac也需要设置

上面我们只是设置了java的,但是javac还没有设置,使用如下命令查看:

javac -version

如果发现显示的版本和java -version显示的版本不一致,那时因为我们切换java的同时还需要切换javac的配置。输入如下命令,然后输入编号2,按enter。再次执行javac -version查看版本是否切换过来即可。

sudo update-alternatives --config javac

三、遇到的问题

1、执行sudo update-alternatives --config java之后,并且选择了对应版本的java,但是执行java -version 显示的还是原来的版本。

# 进入到alternatives目录下,查看java指向是否是自己设置的
cd /etc/alternatives

查看java的指向是否正确,如果没问题,执行如下命令

# 检查自己是否设置了JAVA_HOME
echo $JAVA_HOME


# 检查自己是否配置了PATH
echo $PATH

可以做如下检查:

(1)检查当前会话:首先,确定 JAVA_HOME 是在当前的 shell 会话中设置的,
还是在系统启动时设置的。你可以在一个新的终端窗口中打开一个新的 shell 会话,
然后再次执行 echo $JAVA_HOME 来检查。

(2)检查个人配置文件:如果 JAVA_HOME 在新会话中不存在,那么它可能是在你的个人配置文件中设置的。
检查以下文件:

~/.bashrc
~/.bash_profile
~/.profile
~/.zshrc(如果你使用的是 zsh)

使用文本编辑器或 grep 命令来搜索这些文件中的 JAVA_HOME:

grep -H 'JAVA_HOME' ~/.bashrc ~/.bash_profile ~/.profile ~/.zshrc

(3)检查全局配置文件:如果 JAVA_HOME 不在个人配置文件中,它可能在全局配置文件中设置。
检查以下文件:

/etc/profile
/etc/environment
/etc/bash.bashrc
同样使用 grep 来搜索:

grep -H 'JAVA_HOME' /etc/profile /etc/environment /etc/bash.bashrc

我就是安装JDK17的时候在/etc/profile文件中设置了JAVA_HOME以及PATH,导致使用update-alternatives 设置一直没有生效,后面我把自己设置的都注释掉就好了。

可以使用如下命令编辑:

sudo gedit /etc/profile


# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).

if [ "${PS1-}" ]; then
  if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
    # The file bash.bashrc already sets the default PS1.
    # PS1='\h:\w\$ '
    if [ -f /etc/bash.bashrc ]; then
      . /etc/bash.bashrc
    fi
  else
    if [ "`id -u`" -eq 0 ]; then
      PS1='# '
    else
      PS1='$ '
    fi
  fi
fi

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

# 把下面的这三行注释掉就行了
# export JAVA_HOME=/usr/local/jdk/jdk-17.0.11
# export CLASSPATH=.:$JAVA_HOME/lib
# export PATH=.:$JAVA_HOME/bin:$PATH

注释掉之后使用source /etc/profile刷新配置,但是我自己刷新了之后还是没有生效,果断重启之后,就好了。

source /etc/profile

sudo reboot

2、如果希望保留JAVA_HOME变量,并且希望update-alternatives 配置java之后,能自动刷新JAVA_HOME的配置,可以进行如下操作:

.bashrc 是一个为 Bash shell 编写的配置文件,它包含了用户级的配置和命令,
这些配置和命令会在每次启动新的 Bash shell 会话时被执行。这个文件通常位于
用户的主目录下(即 ~/.bashrc),并且可以被用来个性化用户的 shell 环境。

所以我们可以在~/.bashrc文件下写脚本指定JAVA_HOME的值

执行如下命令编辑.bashrc

sudo gedit ~/.bashrc


然后将如下脚本粘贴进去:

# 函数:自动设置 JAVA_HOME 为默认的 Java 版本
set_java_home() {
    # 使用 update-alternatives 获取默认的 Java 路径
    java_path=$(readlink -f /usr/bin/java)

    # 从默认 Java 路径中提取 JAVA_HOME,去除 "bin/java" 部分
    java_path=$(dirname "$(dirname "$java_path")")

    # 检查路径是否以 "jre" 结尾,如果是,则去除 "jre" 目录
    if [[ "$java_path" == *"/jre" ]]; then
        java_path=$(dirname "$java_path")
    fi

    # 导出 JAVA_HOME 环境变量
    export JAVA_HOME=$java_path

    # 打印当前 JAVA_HOME 值
    # echo "JAVA_HOME is set to: $JAVA_HOME"
}

# 调用函数设置 JAVA_HOME
set_java_home


 保存之后,使用source ~/.bashrc 刷新。

source ~/.bashrc

echo $JAVA_HOME

需要注意的是:如果使用update-alternatives 配置java之后,需要重开一个终端命令窗口才能刷新JAVA_HOME的值。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐