我在 Ubuntu 18.04 上有一个运行 Java 版本 11 的 Jenkins 服务器,通过访问 /manage/systemInfo
检查java.规范.版本 11
我已经基于 Ubuntu 22.04 实现了 docker 构建代理,其中我指定了 java 版本应该是 11:
# install java for Jenkins
RUN apt-get install -qy openjdk-11-jdk
我想知道所有构建节点都处于离线状态,并且阅读日志看到了这一点:
错误:发生 JNI 错误,请检查您的安装并重试 线程“main”中出现异常 java.lang.UnsupportedClassVersionError:hudson/remoting/Launcher 已由更新版本的 Java 运行时(类文件版本 55.0)编译,此版本的 Java 运行时仅识别最高版本 52.0 的类文件
这个问题参考Java类文件格式主要版本号列表?类版本:
52 是 java 8
55 是 java 11
果然,在日志中再往前一点:
[11/14/22 18:35:38] [SSH] 检查java的java版本
[11/14/22 18:35:38] [SSH] java -版本返回1.8.0_312。
所以我去寻找罪魁祸首:
sudo docker container exec 20e1bfe2b182 ls -l /usr/bin/java
回来了
/usr/bin/java -> /etc/alternatives/java
sudo docker container exec 20e1bfe2b182 ls -l /etc/alternatives/java
回来了
/etc/alternatives/java -> /usr/lib/jvm/java-11-openjdk-amd64/bin/java
甚至在安装 opendjk 的行之前将
RUN java -version
注入到我的 Dockerfile 中(这表明没有安装 java...)
在我运行的主机上
apt list --installed |grep jdk
openjdk-11-jdk/bionic-updates,bionic-security,现在 11.0.17+8-1ubuntu2~18.04 amd64 [已安装]
openjdk-11-jdk-headless/bionic-updates,bionic-security,现在 11.0.17+8-1ubuntu2~18.04 amd64 [已安装]
openjdk-11-jre/bionic-updates,bionic-security,现在 11.0.17+8-1ubuntu2~18.04 amd64 [已安装]
openjdk-11-jre-headless/bionic-updates,bionic-security,现在 11.0.17+8-1ubuntu2~18.04 amd64 [已安装,自动]
...docker 镜像上的相同命令给出了类似的结果...
find -name java* 2>/dev/null
从/
运行也没有提供任何有用的东西
which java
输出$ java
/usr/bin/java $ ls -l /usr/bin/java
lrwxrwxrwx 1 root root 22 Nov 24 2018 /usr/bin/java -> /etc/alternatives/java
$ ls -l /etc/alternatives/java
lrwxrwxrwx 1 root root 43 Jan 25 2022 /etc/alternatives/java -> /usr/lib/jvm/java-11-openjdk-amd64/bin/java
$ sudo docker compose run man which java
/usr/bin/java
$ sudo docker compose run man ls -l /usr/bin/java
lrwxrwxrwx 1 root root 11月14日22日20:28 /usr/bin/java -> /etc/alternatives/java
$ sudo docker compose run man ls -l /etc/alternatives/java
lrwxrwxrwx 1 root root 43 十一月 14 20:28 /etc/alternatives/java -> /usr/lib/jvm/java-11-openjdk-amd64/bin/java
echo $PATH
输出$ 回显$PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ sudo docker compose run man echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
将其添加到我的 Dockerfile 中似乎几乎可以解决问题:
RUN ln -s /usr/lib/jvm/java-11-openjdk-amd64/ /home/jenkins/jdk
RUN chown jenkins:jenkins /home/jenkins/jdk
...那么 JDK 8 版本从何而来?
我在这上面浪费了 2 天,我发现我正在运行的 docker 容器安装了两个 JDK(1 个是默认的 centOS7,另一个是我在 Dockerfile 中添加的)。这导致了兼容性问题,因为我的主机上的 DOCKER 在 JDK11 上运行,而 docker 容器(作为从属)选择了 JDK8,因为两个运行时环境都可用。
您可以在 docker 文件中创建并添加一个脚本,以始终选择 JDK11 的运行时
RUN echo 2 | alternatives --config java