扩展我的Gradle Java项目,但遇到编译时间和运行时之间的JDK版本不匹配
我正在开发一个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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
来自Oracle documentation
您的错误说
您已使用Java 17编译,并尝试使用Java 8进行运行。根据上表切换编译或运行编译应用程序的环境。
Docker中存在的 JRE 8 支持 使用JDK 8或更早版本编译的任何代码(1 .. 5,6,7)。
如果您想用 JDK 17 编译该项目,则需要在Docker> = JDK 17 中提供运行环境。
编辑:
回答评论
编译
From oracle documentation
Your error says
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
try with