Fork me on GitHub
#graalvm
<
2024-04-01
>
markaddleman14:04:22

I’m trying to build a native image of an internal clojure service. I can successfully create the binary but when I execute it, I get Could not locate clojure/core/server__init.class, clojure/core/server.clj or clojure/core/server.cljc on classpath . First of all, I’m puzzled why clojure.core.server is being loaded. It’s not referenced in my source. Regardless, I can’t find the right twiddleebits to get around this problem. The relevant clojure.core.server class files are in my uber jar. My native-image command is

native-image -jar target/service-standalone.jar --no-fallback --initialize-at-build-time=org.slf4j.helpers,clojure --initialize-at-run-time=clojure.lang.Compiler
Has anyone seen this problem?

borkdude14:04:03

yes, you need to use --initialize-at-build-time= for every clojure package. when using https://github.com/clj-easy/graal-build-time this will be done automatically

borkdude14:04:39

also probably remove --initialize-at-run-time=clojure.lang.Compiler

markaddleman14:04:00

Doh! I included graal-build-time in my deps.edn but I forgot to add --features=clj_easy.graal_build_time.InitClojureClasses to my native-image command line

greg17:04:31

I'm looking at some examples of compiling Clojure with GraalVM, and I noticed that many sample projects in https://github.com/clj-easy/graalvm-clojure/tree/master, if not all, use:

:aot :all
Same says the guide: https://github.com/clj-easy/graalvm-clojure/blob/master/doc/clojure-graalvm-native-binary.md On the other hand babashka sets:
:main babashka.main
:aot [babashka.main]
I don't assume anything, I'm just curious. Is it better to aot only the main?

borkdude17:04:59

Avoid aot all, it can cause stuff to be compiled twice and cause weird bugs

👍 1
lread21:04:16

@U04V15CAJ I can update the guide and add a tip about aot all being problematic…

👍 1
greg18:04:17

I took graal-build-time 2.0.5 and I noticed this log:

[clj-easy/graal-build-time] Registering packages for build time initialization: clojure, clj_easy.graal_build_time, simplecgt.web.server
Is that correct for list to include clj_easy.graal_build_time ? It sounds like the package is included in the final binary. Shouldn't only facilitate the graalvm compilation?

borkdude18:04:11

Dunno, did you include the dependency on the classpath of the uberjar and did you use aot all? If yes, then don't do that

greg21:04:01

So what I got: • graal-built-time in classpath for uberjar • aot only for main • the only build time flag related to initialize is: --features=clj_easy.graal_build_time.InitClojureClasses Here is this demo: • https://github.com/rynkowsg/simple-cgt-web/blob/main/scripts/compile-native.bash#L17https://github.com/rynkowsg/simple-cgt-web/blob/main/project.clj

borkdude21:04:23

o wait, you do need it

borkdude21:04:59

but I don't think your image will actually contain any of this tool, it's probably how this is supposed to work

borkdude22:04:48

graalvm will cut out anything that is not reachable from your main entry point

greg22:04:01

Tbh I only noticed the log so I was curios whether this end up in the final binary or not

greg22:04:11

oh, nice