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