Another problem arised.
I have a library, let's call it my-lib. This library builds to native image well and pass tests when I run testing image with tests running entry point. I set :aot :all and made lein install .
In another application I put [my-lib "0.1.3"] in dependencies ant trying to build testing native image with same entry point as in library, with same initialization configs and native-image properties (lib config passes via META-INF, I checked reports in both cases). But it fails on initialization stage with Detected a started Thread in the image heap.
The application have extremely small code base ans there is nothing that can interfere... but anyway entry point is inside a library.
Why it can be like that? I'd appreciate for any lead, because I already don't know what to try...
Try to replace :aot :all with :aot [only.your.entry-point.namespace]
aot all compiles the same namespace dependency multiple times which can lead to odd behavior
now on the warning about the thread: this can happen when a thread, e.g. with future , is started on the top level of a namespace
It would be actually nice if you could report back if your previous problems were fixed ;)
> It would be actually nice if you could report back if your previous problems were fixed 😉 Sure I will report all of them when solve complex issue. They all are connected to each other
Okay. I found out that root cause of all troubles was in usual dependency conflict. Unfortunately I wasn't so experienced to recognize it in native-image error messages
Found this, will try to see whether I can make progress https://github.com/clj-easy/graal-docs?tab=readme-ov-file
@whilo native-image + clojure doesn't work without initialize-at-build-time
Right, I figured that out. Our older GraalVM version build pipeline through warnings at me about it, that is why I had removed it.
We built this to deal with the warning: https://github.com/clj-easy/graal-build-time
Yes, I added it, but now my binary is even bigger. I fear there is a resolve call somewhere, but couldn't find it in the tracing reports yet.
I've added this to babashka once to detect requires at runtime:
(def enable-require-scan
"(do
(def old-require require)
(def old-resolve resolve)
(def our-requiring-resolve (fn [sym]
(let [ns (symbol (namespace sym))]
(old-require ns)
(old-resolve sym))))
(defn static-requiring-resolve [form _ _]
(prn :req-resolve form :args (rest form))
`(let [res# (our-requiring-resolve ~@(rest form))]
res#))
(alter-var-root #'requiring-resolve (constantly @#'static-requiring-resolve))
(doto #'requiring-resolve (.setMacro))
(defn static-require [& [&form _bindings & syms]]
(when (meta &form)
(prn :require &form (meta &form) *file*))
`(old-require ~@syms))
(alter-var-root #'require (constantly @#'static-require))
(doto #'require (.setMacro))
(alter-var-root #'clojure.core/serialized-require (constantly (fn [& args]
(prn :serialized-req args)))))
(defn static-resolve [& [&form _bindings & syms]]
(when (meta &form)
(prn :require &form (meta &form) *file*))
`(old-resolve ~@syms))
(alter-var-root #'resolve (constantly @#'static-resolve))
(doto #'resolve (.setMacro))
")
(when (System/getenv "BABASHKA_REQUIRE_SCAN")
(load-string enable-require-scan))Oh, cool. Thanks!
@borkdude I am trying to help @sasha_bogdanov_dev by trying to shrink the datahike native image size (including pod) finally as we discussed in the past. I get " Could not locate clojure/core__init.class" at runtime when I remove "--initialize-at-build-time" from the compilation flags. In babashka you did not seem to using tracing like this https://www.graalvm.org/latest/reference-manual/native-image/guides/configure-with-tracing-agent/. How did you make sure you don't have these runtime errors?
Thanks a lot, @whilo, but in particular this moment I am more trying to understand why snap start is not working for my case…