oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀
https://www.graalvm.org
Other
20.21k stars 1.62k forks source link

Experience report: unexpected filename based caching for native-image --jar #733

Closed jeroenvandijk closed 5 years ago

jeroenvandijk commented 5 years ago

I was trying to compiling a jar with native-image [1]. I did this for two Clojure versions, but both with the same output filename. It seemed GraalVM looked just at the name/location of the jar and not it's content and decided it could use the previous version. (should be Clojure version 1.10.0-RC1, but was Clojure version 1.8.0 before the rename of the jar)

The log of this session is in this commit. I can see what jar it was using based on the above mentioned print statement in the different jars.

I also saw that multiple invocations of native-image change the stacktrace. It reminded my of a JVM optimization that you have to turn off with -OmitStackTraceInFastThrow. Another indication of this was is that subsequent native-image calls were a lot faster. I wonder how this affects the result (given the first error). My hope is that independent calls are isolated from each other

[1] Complete background here https://github.com/dundalek/closh/issues/93

olpaw commented 5 years ago

Hi @jeroenvandijk

It seemed GraalVM looked just at the name/location of the jar and not it's content and decided it could use the previous version.

This should not happen. The is no such reuse-logic in native-image. Can you send me links to your two variants of target/project.jar so that I can reproduce/debug the problem?

olpaw commented 5 years ago

Another indication of this was is that subsequent native-image calls were a lot faster.

This is the effect of the image-build server. On first use native-image spawns a JVM that does image-building and reuses that JVM on subsequent image builds. It gets faster and faster because the reused JVM gets into a fully warmed up state where it performs image-building more efficient. Usually there should be proper isolation between subsequent calls of the image-build server (only use of static fields in classes from the bootclasspath could cause leaking state from one image-build to the next).

Note that if you do not trust the image-build server you can always use native-image --no-server to prevent it from getting used. For more info see: native-image --help-extra

olpaw commented 5 years ago

@jeroenvandijk at least with dummy versions of target/project.jar I'm not able to reproduce your problem.

native-image-jar-workflow.log

jeroenvandijk commented 5 years ago

@olpaw I'm not able to reproduce it anymore either. I'll report back when I see it again and I'll make sure to keep the artefacts. Please consider it false alarm until then, my apologies.