We are new to Graalvm and are building a simple Java command line app. The jar runs fine in jvm mode (java -jar <file>.jar
). We don’t install Graalvm on our machines (yet) so we tried to create the native image from inside Docker container which runs Graalvm, the Dockerfile is this simple:
FROM ghcr.io/graalvm/native-image:ol8-java17
COPY . /home/app
WORKDIR /home/app
RUN ./mvnw clean package
RUN native-image -cp target/appj-1.0.0.jar "org.nqm.Appj"
RUN mv org.nqm.Appj appj
RUN chmod +x appj
The docker image was successfully built.
Then we tried to access the container (docker run --rm --name dkappj -it --entrypoint bash dkappj
) to collect the native image file. From inside the docker container, we could run it with ./appj
without any errors.
However, when we copied the native image file to the host machine and run it with ./appj
it produces an error:
zsh: exec format error: ./appj
So my question is can we create native image from inside a graalvm docker container, copy it and run it anywhere? Or we have to install Graalvm on our host machine to be able to execute the native image? Because I thought graalvm native image is actually the machine code (like the apps created from C language)
Edit:
when I replicated the whole code base on a new computer which runs the same os (ubuntu 20.04) the native image runs fine on that host machine.
2
Answers
(answer to my own question)
The answer is YES!
For some specific reasons I am now able to build the native image file inside docker container and run it.
I think you can by doing this way, https://github.com/swseighman/Spring-GraalVM-REST-Example/blob/main/src/main/resources/containers/Dockerfile.stage
I tried doing the same and it did not work as you got to use same architecture to build and run the image. Linux built image would run on Linux and so as macOS built on mac. I use builtpacks and it give you OCI image which runs perfectly fine.