Question

When using the maven-shade-plugin to package our jar artifact that contained a few Clojure libs and some Java. We were using AOT compilation for our Clojure code. When we loaded the jar, it was having very slow load times. AOT compilation is supposed to help this quite a bit, but that wasn't what we were seeing. We noticed in java jar -verbose output that there was a lot of JVM__DEFINE_CLASS calls happening when Clojure classes were being loaded.

This didn't make sense, since more of our Clojure code was AOT compiled to .class files.

Turns out the maven-shade-plugin creates all new files, with new timestamps in the final artifact Clojure uses the timestamp information on a .clj file vs. a .class file, to determine if the file needs to be recompiled. The maven-shade-plugin was causing the .clj file and it's associated .class file to have the same timestamp, so Clojure always chose to dynamically recompile the source.

The only workaround that we have been able to figure out, at this point, is to write a script that would re-open the shaded jar and bump the .clj file timestamps back to some time in the past, so that they wouldn't be equal to the timestamps of their associated .class files.

Does anyone know of a better approach?

Was it helpful?

Solution

Not sure if this is better, but you can also choose to exclude the clojure source from the jar. This will prevent them being recompiled. I ran into this when building with lein and compressing with pack200. Further details here:

jar built with jwrapper doesn't work

Not sure of the maven options for excluding files, but with lein you can drop in an exclude pattern, like #".(clj|java)" to exclude source files.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top