扩展我的Gradle Java项目,但遇到编译时间和运行时之间的JDK版本不匹配

发布于 2025-02-11 23:36:37 字数 4450 浏览 0 评论 0原文

我正在开发一个Gradle Java项目(纯Java不是Spring-boot)。

我将项目与多阶段Dockerfile进行对接,以减少最终图像大小:

FROM gradle:7.4.2-alpine as builder
WORKDIR /home/app
COPY . .
RUN gradle :myapp:build

FROM openjdk:8-jre-alpine as my-app
WORKDIR /app
COPY --from=builder /home/app/MyApp/build/libs/MyApp-1.0-SNAPSHOT.jar /app/
ENTRYPOINT ["java", "-jar", "/app/MyApp-1.0-SNAPSHOT.jar"]

如上所述,我使用的是基本图像OpenJDK:8-JRE-Alpine用于运行应用程序jar。我选择它是基本图像,因为它非常苗条。

我通过docker build -t myApp。&构建项目。它是成功的。

我通过Docker运行MyApp运行它,但是我会发现错误:

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError: com/MyApp has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)

我对错误的解释是我的Java类是用更高的JDK版本构建的,而在运行时,我选择OpenJDK: 8-jre-alpine正在使用旧版本的JRE运行。 (如果我在这里错了,请纠正我。)

我想继续使用该基本图像,因为它的尺寸很小。因此,我决定使用Java 11 JDK编译代码。

在我的build.gradle中添加以下内容来指定较旧的Java版本:

java {
  toolchain {
    languageVersion.set(JavaLanguageVersion.of(11))
  }
}

我尝试通过 我会发现构建错误:

#12 45.30 Could not determine the dependencies of task ':myapp:compileJava'.
#12 45.30 > Could not resolve all dependencies for configuration ':common:compileClasspath'.
#12 45.30    > Failed to calculate the value of task ':myapp:compileJava' property 'javaCompiler'.
#12 45.31       > Provisioned toolchain '/home/gradle/.gradle/jdks/adoptium-11-x64-hotspot-linux' could not be probed.

我想那是因为我使用的基本图像没有JDK? (如果我在这里错误地理解的话,请纠正我),

所以,我想知道让我的项目由Java 11 JDK&我仍然可以使用那个基本图像吗?

=======更多尝试i did ======

我忘了提到我也猜到了图像openjdk:8-jre-alpine可能会暗示它仅支持它Java-8,所以我将其重命名为OpenJDK:Java-11的11-jre-alpine,当构建图像时,我遇到以下错误时,我想这意味着图像不存在?

[+] Building 1.5s (6/6) FINISHED                                                                                                                                                                                        
 => [internal] load build definition from Dockerfile                                                                                                                                                               0.0s
 => => transferring dockerfile: 386B                                                                                                                                                                               0.0s
 => [internal] load .dockerignore                                                                                                                                                                                  0.0s
 => => transferring context: 34B                                                                                                                                                                                   0.0s
 => ERROR [internal] load metadata for docker.io/library/openjdk:11-jre-alpine                                                                                                                                     1.4s
 => CANCELED [internal] load metadata for docker.io/library/gradle:7.4.2-alpine                                                                                                                                    1.4s
 => [auth] library/gradle:pull token for registry-1.docker.io                                                                                                                                                      0.0s
 => [auth] library/openjdk:pull token for registry-1.docker.io                                                                                                                                                     0.0s
------
 > [internal] load metadata for docker.io/library/openjdk:11-jre-alpine:
------
failed to solve with frontend dockerfile.v0: failed to create LLB definition: docker.io/library/openjdk:11-jre-alpine: not found

I am developing a gradle java project (it is pure java not spring-boot).

I dockerize the project with multi-stage Dockerfile in order to slim the final image size:

FROM gradle:7.4.2-alpine as builder
WORKDIR /home/app
COPY . .
RUN gradle :myapp:build

FROM openjdk:8-jre-alpine as my-app
WORKDIR /app
COPY --from=builder /home/app/MyApp/build/libs/MyApp-1.0-SNAPSHOT.jar /app/
ENTRYPOINT ["java", "-jar", "/app/MyApp-1.0-SNAPSHOT.jar"]

As you see above, I am using base image openjdk:8-jre-alpine for running the application jar. I choose it as base image because it is very slim.

I build the project by docker build -t myapp . & it is successful.

I run it by docker run myapp, however I get error:

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError: com/MyApp has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)

My interpretation of the error is my Java class is built with a higher JDK version while at runtime the the base image I choose openjdk:8-jre-alpine is using an older version JRE to run. (Please correct me if I am wrong here.)

I would like to keep using that base image because it is small in size. So I decided to compile my code using java 11 jdk.

I tried specifying the older java version for building project by adding the following in my build.gradle :

java {
  toolchain {
    languageVersion.set(JavaLanguageVersion.of(11))
  }
}

and then, build the image again docker build -t myapp ., but now I get building error:

#12 45.30 Could not determine the dependencies of task ':myapp:compileJava'.
#12 45.30 > Could not resolve all dependencies for configuration ':common:compileClasspath'.
#12 45.30    > Failed to calculate the value of task ':myapp:compileJava' property 'javaCompiler'.
#12 45.31       > Provisioned toolchain '/home/gradle/.gradle/jdks/adoptium-11-x64-hotspot-linux' could not be probed.

I guess that is because the base image I use doesn't have that jdk?? (Please correct me if I understood wrongly here)

So, I wonder what is the proper way to have my project being built by java 11 jdk & I could still use that base image?

===== More try I did =====

I forgot to mention that I also guessed the image openjdk:8-jre-alpine might hint it only support java-8, so I renamed it to openjdk:11-jre-alpine for java-11, when build the image I encounter the following error, I guess it means the image doesn't exist?

[+] Building 1.5s (6/6) FINISHED                                                                                                                                                                                        
 => [internal] load build definition from Dockerfile                                                                                                                                                               0.0s
 => => transferring dockerfile: 386B                                                                                                                                                                               0.0s
 => [internal] load .dockerignore                                                                                                                                                                                  0.0s
 => => transferring context: 34B                                                                                                                                                                                   0.0s
 => ERROR [internal] load metadata for docker.io/library/openjdk:11-jre-alpine                                                                                                                                     1.4s
 => CANCELED [internal] load metadata for docker.io/library/gradle:7.4.2-alpine                                                                                                                                    1.4s
 => [auth] library/gradle:pull token for registry-1.docker.io                                                                                                                                                      0.0s
 => [auth] library/openjdk:pull token for registry-1.docker.io                                                                                                                                                     0.0s
------
 > [internal] load metadata for docker.io/library/openjdk:11-jre-alpine:
------
failed to solve with frontend dockerfile.v0: failed to create LLB definition: docker.io/library/openjdk:11-jre-alpine: not found

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

话少心凉 2025-02-18 23:36:37

来自Oracle documentation

java se |释放|专业|支持的专业

1.0.2 | 1996年5月| 45 | 45

1.1 | 1997年2月| 45 | 45

1.2 | 1998年12月| 46 | 45 .. 46

1.3 | 2000年5月| 47 | 45 .. 47

1.4 | 2002年2月| 48 | 45 .. 48

5.0 | 2004年9月| 49 | 45 .. 49

6 | 2006年12月| 50 | 45 .. 50

7 | 2011年7月| 51 | 45 .. 51

8 | 2014年3月| 52 | 45 .. 52

9 | 2017年9月| 53 | 45 .. 53

10 | 2018年3月| 54 | 45 .. 54

11 | 2018年9月| 55 | 45 .. 55

12 | 2019年3月| 56 | 45 .. 56

13 | 2019年9月| 57 | 45 .. 57

14 | 2020年3月| 58 | 45 .. 58

15 | 2020年9月| 59 | 45 .. 59

16 | 2021年3月| 60 | 45 .. 60

17 | 2021年9月| 61 | 45 .. 61

18 | 2022年3月| 62 | 45 .. 62

您的错误说

是由Java Runtime的最新版本编译的(班级
文件版本61.0 ),此版本的Java运行时仅识别
类文件版本最多52.0

您已使用Java 17编译,并尝试使用Java 8进行运行。根据上表切换编译或运行编译应用程序的环境。

Docker中存在的 JRE 8 支持 使用JDK 8或更早版本编译的任何代码(1 .. 5,6,7)

如果您想用 JDK 17 编译该项目,则需要在Docker> = JDK 17 中提供运行环境。

编辑

回答评论

我也想知道我应该使用什么图像来运行代码
由JDK 17

编译

编译

FROM openjdk:17-alpine as my-app ...

From oracle documentation

Java SE | Released | Major | Supported majors

1.0.2 | May 1996 | 45 | 45

1.1 | February 1997 | 45 | 45

1.2 | December 1998 | 46 | 45 .. 46

1.3 | May 2000 | 47 | 45 .. 47

1.4 | February 2002 | 48 | 45 .. 48

5.0 | September 2004 | 49 | 45 .. 49

6 | December 2006 | 50 | 45 .. 50

7 | July 2011 | 51 | 45 .. 51

8 | March 2014 | 52 | 45 .. 52

9 | September 2017 | 53 | 45 .. 53

10 | March 2018 | 54 | 45 .. 54

11 | September 2018 | 55 | 45 .. 55

12 | March 2019 | 56 | 45 .. 56

13 | September 2019 | 57 | 45 .. 57

14 | March 2020 | 58 | 45 .. 58

15 | September 2020 | 59 | 45 .. 59

16 | March 2021 | 60 | 45 .. 60

17 | September 2021 | 61 | 45 .. 61

18 | March 2022 | 62 | 45 .. 62

Your error says

has been compiled by a more recent version of the Java Runtime (class
file version 61.0), this version of the Java Runtime only recognizes
class file versions up to 52.0

You have compiled with JAVA 17 and try to run it with JAVA 8. Switch either the compilation or the environment that runs the compiled application according to the above table.

Your JRE 8 that exists in docker supports any code that is compiled with JDK 8 or earlier versions (1 .. 5, 6, 7) .

If you wish to compile the project with JDK 17 you need to provide a running environment in docker >= JDK 17.

Edit:

Answering the comment

I also wonder what is the image I should use to run the code that is
compiled by JDK 17

try with

FROM openjdk:17-alpine as my-app ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文