【问题标题】:Docker run returns an exception: Application has been compiled by a more recent version of the Java RuntimeDocker 运行返回异常:应用程序已由更新版本的 Java 运行时编译
【发布时间】:2021-01-12 11:07:00
【问题描述】:

我使用 Springboot 创建了一个 Web 应用程序,现在我要将其 dockerize 并将其上传到 docker hub。所以我的Dockerfile 是,

FROM openjdk:8

EXPOSE 8080

ADD target/spring-boot-web-0.0.1-SNAPSHOT.jar spring-boot-web-0.0.1-SNAPSHOT.jar

ENTRYPOINT ["java","-jar","spring-boot-web-0.0.1-SNAPSHOT.jar"]

在我的目标中创建 .jar 后,我正在使用以下命令构建 docker 映像,

docker build -t kubernatesimage

它成功构建了 docker 镜像,当我运行 docker images 时,我可以看到创建的镜像。但在将其上传到 docker hub 之前,我需要运行并检查以便执行,

docker run -it  -p 4000:80 kubernatesimage 

这会返回以下异常,

线程“main”中的异常 java.lang.UnsupportedClassVersionError: guru/springframework/SpringBootWebApplication 已由更新版本的 Java Runtime(类文件版本 55.0)编译,此版本的 Java Runtime 仅识别类文件版本高达 52.0

根据@Nithin 在this StackOverflow 问题中的回答,我发现这是由于版本不匹配和 java 版本代码造成的,

49 = Java 5
50 = Java 6
51 = Java 7
52 = Java 8
53 = Java 9
54 = Java 10
55 = Java 11
56 = Java 12
57 = Java 13
58 = Java 14

但是,我仍然不知道我需要执行什么来解决问题。我在 Dockerfile 中提到了 openjdk:8,然后我运行 java -version 来获取本地 JDK 版本并返回

java version "1.8.0_271"

那么我需要在本地机器上更改 java 版本还是更改我的Dockerfile

【问题讨论】:

  • 您必须使用您的 docker 使用的版本重新编译代码,或者您必须更新运行时环境的 java 版本。哪个,是你的决定。
  • @Stultuske 你好,我如何检查我的 docker 使用的 java 版本是否有任何命令?
  • 都在错误信息中:这个版本的 Java Runtime 只能识别最高 52.0 的类文件版本
  • 在本地和docker尝试相同的版本,希望能解决
  • @HasanuzzamanRana 所以我需要删除当前的 docker 镜像并重建它

标签: java spring-boot docker java-8


【解决方案1】:

您的应用程序不应该以任何一种方式运行,因为docker run -it -p 4000:80 kubernatesimage 它应该是docker run -it -p 4000:8080 kubernatesimage

现在关于这个问题:您的运行时版本是 8:因为您的 dockerfile 是“FROM openjdk:8”所以您的应用程序将在 java 8 环境中运行 =>版本 52 .. 并且您已将您的应用程序编译为另一个版本 55 即 java 11 的 jar 文件“spring-boot-web-0.0.1-SNAPSHOT.jar”。所以您有 java 版本不匹配 => 关键是要确保编译和运行时使用相同的JDK。

一个建议的解决方法是在 pom.xml 文件中更改您的 java 版本

<project>
...
 <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
...
</project>

另一个解决方法是将 dockerfile 中的运行时版本更改为 java 11 ,无法将您的图像基于 openjdk:11 但是您可以使用它

FROM adoptopenjdk/openjdk11:alpine-jre
ARG JAR_FILE=target/*.jar
WORKDIR /opt/app
COPY ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]

注意:您仍然可以在较大的运行时环境中运行较小的已编译 java 版本,即在 java 11 运行时环境中运行已编译的 8 java 版本

希望能帮到你

【讨论】:

  • 用1.8编译的jar可以用Java 11启动,所以using the same JDK不是必须的。
  • 另一种方式是发生了什么。这就是为什么我建议你使用相同的版本
猜你喜欢
  • 2018-06-01
  • 2022-07-25
  • 1970-01-01
  • 1970-01-01
  • 2021-12-01
  • 2022-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多