我有两台 Ubuntu 20.04 服务器,Alpha 和 Beta,都安装了从标准存储库安装的 Tomcat 9。原则上,它们实际上应该是相同的,但我发现每个使用的 Java 版本存在差异,但我无法找到其来源。
在服务器 Alpha 上,Tomcat 的
ps
进程列表和 systemctl status tomcat9.service
都显示其 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 配置文档中找不到这个问题的答案,并且文档中没有其他似乎与这个问题相关的顶级主题。
2)堆栈溢出
这个 Stack Overflow 问题 是我在网站上能找到的最好的问题,它没有任何针对 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/
目录)都不存在于任一服务器上,因此这无法解释其中的差异。
我能想到的就是这些。问题是:
在没有显式用户配置的情况下,什么决定了Tomcat使用什么Java版本?这些信息必须存储在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
测试版。
在 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
存在则选择,一般来说,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
我刚刚遇到的问题是我想使用 java 版本 8 而不是默认版本来运行 tomcat。
我编辑
/usr/libexec/tomcat9/tomcat-locate-java.sh
。我补充一下:
# run tomcat with Java version 8
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
在文件开头。要获得可能的值,请执行以下操作:
$ls -l /usr/lib/jvm
default-java -> java-1.11.0-openjdk-amd64
java-1.11.0-openjdk-amd64 -> java-11-openjdk-amd64
java-11-openjdk-amd64
java-1.8.0-openjdk-amd64 -> java-8-openjdk-amd64
java-8-openjdk-amd64