I used the hello word Java app produced with gradle init. And I want to run it in docker. Here is my docker file:
FROM gradle:7.5.1-jdk11 AS builder
COPY . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle installDist
FROM openjdk:18.0.2.1-oracle
RUN microdnf install findutils
COPY --from=builder /home/gradle/src/build/install/app/ /app/
WORKDIR /app
CMD bin/app
It runs ok only when the second running image has a Java18. I'm really confused here, the first builder image has Java11. Why the gradle in image isn't configured to use system's JDK version? If it always uses it's own JDK. Why bother shipping a JDK11 with the gradle image?
Also, docker noob question: There are so many JDK / JRE images out there, how do you guys pick which one to use? Any preference ranking or something similar?
I did another try. Only use the first part of the docker file
FROM gradle:7.5.1-jdk11 AS builder
COPY . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle installDist
Then docker build --tag second-try .
Then docker run -it second-try /bin/bash
I went into the build/install/app/lib folder and unpacked the app.jar jar xf app.jar
to get the compiled class file. Then javap -v App.class | grep major
to get the compiling JDK version. The version is 62 which is Java18.
CodePudding user response:
Why the gradle in image isn't configured to use system's JDK version?
It's the case. Gradle, in the builder image, is using the system JDK. You can test it by running java --version
and gradle --version
inside the container:
$ docker run -it gradle:7.5.1-jdk11 /bin/sh
# java --version
openjdk version "11.0.16.1" 2022-08-12
OpenJDK Runtime Environment Temurin-11.0.16.1 1 (build 11.0.16.1 1)
OpenJDK 64-Bit Server VM Temurin-11.0.16.1 1 (build 11.0.16.1 1, mixed mode, sharing)
# gradle --version
------------------------------------------------------------
Gradle 7.5.1
------------------------------------------------------------
Build time: 2022-08-05 21:17:56 UTC
Revision: d1daa0cbf1a0103000b71484e1dbfe096e095918
Kotlin: 1.6.21
Groovy: 3.0.10
Ant: Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM: 11.0.16.1 (Eclipse Adoptium 11.0.16.1 1)
OS: Linux 5.10.104-linuxkit aarch64
The final image is running OpenJDK 18, which can run Java 11 bytecode.
CodePudding user response:
Ok, I figured it out. I overlooked the fact that gradle installDist produce the build/install/<app>/bin/<app>
according to the folder name.
So when COPY . /home/gradle/src
, I included local built jar files which is under build/install/app/bin/src
because my local folder name is app. But when installDist runs during docker image build, the folder name is src. The output is build/install/src/bin/src
.
Below is the fixed docker file which can be run with Java17
FROM gradle:7.5.1-jdk11 AS builder
COPY . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle clean
RUN gradle installDist
FROM openjdk:17-oracle
RUN microdnf install findutils
COPY --from=builder /home/gradle/src/build/install/src/ /app/
WORKDIR /app
CMD bin/src
Adding a gradle clean is a best practice that will throw error if the path is wrong.
Thanks to Ortomala Lokni, I now know a way to get the shell running in docker so that I can do more debugging