This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-10-05
Channels
- # announcements (14)
- # aws (7)
- # babashka (28)
- # beginners (16)
- # calva (2)
- # cider (1)
- # clj-commons (8)
- # clj-kondo (29)
- # clojure (213)
- # clojure-europe (39)
- # clojure-losangeles (2)
- # clojure-norway (9)
- # clojure-spec (2)
- # clojurescript (11)
- # community-development (1)
- # conjure (2)
- # cursive (6)
- # datalevin (2)
- # datomic (8)
- # emacs (29)
- # events (1)
- # fulcro (22)
- # graalvm (14)
- # improve-getting-started (1)
- # jobs (1)
- # lambdaisland (5)
- # leiningen (4)
- # lsp (7)
- # malli (13)
- # meander (11)
- # membrane (13)
- # off-topic (23)
- # polylith (9)
- # re-frame (4)
- # reagent (7)
- # reitit (6)
- # releases (2)
- # sql (58)
- # testing (8)
- # tools-deps (18)
- # web-security (2)
Hello, I'm attempting to build a native executable with native-image. I've been able to successfully produce an executable with a fairly minimal application, but after making some changes to the program, I am getting the following error:
Fatal error: org.graalvm.compiler.debug.GraalError: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of org.apache.commons.logging.impl.LogFactoryImpl are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use --trace-object-instantiation=org.apache.commons.logging.impl.LogFactoryImpl.
I do have https://github.com/clj-easy/graal-build-time in the project, which gave me success in the first place, but it appears there's more to do.
In an attempt to heed the error message, I added the specified class to an --initialize-at-run-time
flag, but this doesn't fix the error:
native-image --initialize-at-run-time=org.apache.commons.logging.impl.LogFactoryImpl -jar ..\app-0.1.0-SNAPSHOT-standalone.jar
I also attempted adding a flag for the absract parent class:
--initialize-at-run-time=org.apache.commons.logging.LogFactory
https://commons.apache.org/proper/commons-logging/apidocs/org/apache/commons/logging/impl/LogFactoryImpl.html
https://commons.apache.org/proper/commons-logging/apidocs/org/apache/commons/logging/LogFactory.html
Any insights on how to proceed?
Perhaps more generally, if we get the No instances of <OFFENDING CLASS> are allowed in the image heap as this class should be initialized at image runtime.
error, then how can one determine the root cause and fix it? I'm stumped as to why the --initialize-at-run-time
flag seems to have no effect.This error can happen when you instantiate the logger in a Clojure namespace on the top level. Since top level expressions are executed at image build time, it will then also initialize the logger at build time
I'm not instantiating the logger anywhere intentionally--so maybe something with a library. When I disable call to mount/start-with-args
in my -main
function then I'm able to build the native executable successfully. The`mount`library does appear to be addressed by graal-build-time
so I don't know why calling this function triggers the error. I have 2 defstates
, one that calls a next.jdbc
function, and one that calls a clj-http
function. I assume the logger is instantiated somewhere between those elements.
Yes, I believe so (https://github.com/tolitius/mount#creating-state).
Attempting to build with the mount state refactored into atoms worked but with a warning that it requires JDK for execution (which is a different issue). Would the global state thing make mount strictly incompatible for inclusion in a native executable?
I guess the packages registered by graal-build-time are dynamically determined and not necessarily supported in graalvm builds. I'll just get rid of mount for this application. Thanks for the help!
Unfortunately, I spoke too soon and am still getting the same LogFactoryImpl
error after removing mount
. I have no idea how I had a successful build when first refactoring out mount usages, as I cannot repeat it. Now, the error is given every time I call a function in -main
that ultimately calls jdbc/execute!
from the next.jdbc
library.
How I usually approach is to try to make the smallest example possible that still reproduces the error, and then try to find a solution
Yeah, that's the line I'm pursuing. I suspect the issue may come from the https://ucanaccess.sourceforge.net/site.html#home jdbc driver I'm using with next.jdbc
to connect to an MS Access database. Is it possible to configure the native-image build to force a 3rd party library to initialize a class at runtime? I don't know if that's the right question, but I'm not sure how to proceed from here.
You can only initialize at runtime if the instance isn't initialized already at build time which may be the case in your application
I'll probably fall back to just working with the .jar for now. It would be much nicer to distribute a faster, batteries-included native executable, but unfortunately that may not be possible, or at least not worth the trouble for this case.