什么决定了 Java Tomcat 在 Ubuntu 上使用哪个版本?

What determines which version of Java Tomcat uses on Ubuntu?

我有两台 Ubuntu 20.04 服务器,Alpha 和 Beta,都从标准存储库安装了 Tomcat 9。原则上,它们应该几乎相同,但我发现 Java 各自使用的版本存在差异,我无法找到其来源。

在服务器 Alpha 上,Tomcat 和 systemctl status tomcat9.serviceps 进程列表都显示其 Java 二进制文件是 /usr/lib/jvm/java-8-openjdk-amd64/bin/java。在服务器 Beta 上,相同的命令显示 Tomcat 的 Java 二进制文件是 /usr/lib/jvm/default-java/bin/java,它是 /usr/lib/jvm/java-1.11.0-openjdk-amd64/bin/java.

的符号链接

因此,服务器 Alpha 使用 Java 8,而服务器 Beta 使用 Java 11。它们应该是相同的,但有些地方明显不同。

此时明显的问题是,Tomcat如何确定使用哪个版本的Java?

1) 文档

我在 Tomcat configuration documentation 中找不到这个问题的答案,文档中也没有其他与这个问题相关的顶级主题。

2) 堆栈溢出

这个 Stack Overflow question 是我在网站上能找到的最好的,它没有任何对 Ubuntu 系统有用的答案; /etc/sysconfig/tomcat{N} 在一个答案中被提及,但它在任何一个服务器上都不存在,而 /etc/default/tomcat{N} 在两个服务器上都存在但不包含与 Java 版本相关的任何参数。

3) 标准配置文件

我还检查了主 Tomcat 配置文件 /var/lib/tomcat9/conf/server.xml 和 Tomcat systemd 服务文件 /lib/systemd/system/tomcat9.service,但两者都不包含任何与Java 版本。两台服务器都有一个服务文件覆盖 /etc/systemd/system/tomcat9.service.d/override.conf,但由于我自己写了它,所以我确定它没有设置使用的 Java 版本。

4) setenv.sh

Tomcat 的 /usr/share/tomcat9/bin/catalina.sh 文件提到了一个 JAVA_HOME 环境变量,我必须假设这就是我要找的。该文件似乎希望在它获取两个文件之一 $CATALINA_BASE/bin/setenv.sh$CATALINA_HOME/bin/setenv.sh 时设置此变量。这些文件(或 bin/ 目录,甚至)都不存在于任一服务器上,因此这无法解释差异。

我能想到的就这么多。问题是:

在没有显式用户配置的情况下,是什么决定了Java版本Tomcat使用的?这些信息必须存储在其中一个文件中Tomcat的安装,不知道是哪个

编辑

正如@Emerson Pardo 所建议的,Ubuntu 20.04 did 的两个实例具有不同的默认 Java 版本。在使用 Debian/Ubuntu update-alternatives 程序将 Beta 更改为使用 Java 8 并重新启动 Tomcat 后,上面列出的问题没有改变。 Tomcat继续使用

/usr/lib/jvm/default-java/bin/java -> /usr/lib/jvm/java-1.11.0-openjdk-amd64/bin/java

测试版。

一般Ubuntu选择Java默认使用的。你可以这样找到它:

$ which java
/usr/bin/java
$/usr/bin/java --version
openjdk 11.0.11 2021-04-20                                                                                                                                                         
OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.18.04)                                                                                                                
OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.18.04, mixed mode, sharing)     

您还可以使用以下方法检查系统中可用的替代方案:

$ update-java-alternatives -l 

这将列出所有 java 安装。

要选择特定版本,您可以使用:

$ sudo update-alternatives --config java

在 Debian 10 的衍生版本上,例如 Ubuntu 20.04,Tomcat 通过位于 /usr/libexec/tomcat9/tomcat-start.sh 中的包装脚本启动。如果您不自己设置 JAVA_HOME,则会在 /usr/libexec/tomcat9/tomcat-locate-java.sh:

中执行启发式过程
    # This function sets the variable JDK_DIRS
    find_jdks()
    {
        for java_version in 11 10 9 8
        do
            for jvmdir in /usr/lib/jvm/java-${java_version}-openjdk-* \
                          /usr/lib/jvm/jdk-${java_version}-oracle-* \
                          /usr/lib/jvm/jre-${java_version}-oracle-* \
                          /usr/lib/jvm/java-${java_version}-oracle \
                          /usr/lib/jvm/oracle-java${java_version}-jdk-* \
                          /usr/lib/jvm/oracle-java${java_version}-jre-*
            do
                if [ -d "${jvmdir}" ]
                then
                    JDK_DIRS="${JDK_DIRS} ${jvmdir}"
                fi
            done
        done
    }

    # The first existing directory is used for JAVA_HOME
    JDK_DIRS="/usr/lib/jvm/default-java"
    find_jdks

    # Look for the right JVM to use
    for jdir in $JDK_DIRS; do
        if [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; then
            JAVA_HOME="$jdir"
        fi
    done
    export JAVA_HOME

因此:

  • 如果 /usr/lib/jvm/default-java 存在,则选择它,
  • 否则使用 Java 的最高(最多 11)版本。