Fork me on GitHub
#graalvm
<
2022-09-19
>
Rick Suijkerbuijk08:09:44

Hi everyone, We're currently trying to build a native image out of our clojure application but we're running into some bumps. If we build with native-image [ARGS] --initalize-at-build-time it works like a charm but we get the warning that --initalize-at-build-time will be deprecated in the future, so obviously we are trying to avoid using the global flag. However this raises a problem. We use clj-easy to manage the packages for build time initialization registry but that library wont register single segment packages which leaves us with the following problem:

[clj-easy/graal-build-time] WARN: Single segment package found for class: primitive_math__init.class. This class has no package and it will not be added to the result packages.
And causes the build to fail:
2 fatal errors detected:
Fatal error: org.graalvm.compiler.debug.GraalError: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of primitive_math$_LT__LT_ 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=primitive_math$_LT__LT_.

Fatal error: org.graalvm.compiler.debug.GraalError: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of primitive_math$ns_wrapper$fn__6326 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=primitive_math$ns_wrapper$fn__6326.
Does anybody have an idea how to include primitive_math manually to --initalize-at-build-time ? We tried --initalize-at-build-time=primitive_math and some variations to it but with no success. Thanks in advance!

borkdude08:09:06

@rick.suijkerbuijk Yes, use primitive-math from here: https://github.com/clj-commons/primitive-math/tree/master/src/clj_commons It now has a multi-segment namespace

Rick Suijkerbuijk08:09:57

Forgot to mention, we do not use primitive-math ourselves but our lancaster library uses it which causes a cascading effect

borkdude08:09:18

then upgrade primitive math in lancaster

Bart Kleijngeld08:09:13

@borkdude Lancaster depends on the latest 1.0.0 version already

Bart Kleijngeld08:09:46

(Also: if the version was the problem, I wouldn't understand why the global --initalize-at-build-time does work)

Bart Kleijngeld08:09:38

(Oh, you mean upgrade to the version of the master branch perhaps?)

borkdude08:09:46

If the Lancaster library still requires the single segment namespace that won't help. You need to avoid loading that

Rick Suijkerbuijk08:09:24

but then the question how come the global --initalize-at-build-time manages to catch this and if you try to feed it by hand it wont register?

borkdude08:09:55

Because you need to give it either class names or regexes and those assume a package name. Single segment namespaces compile to classes without packages

Rick Suijkerbuijk08:09:07

so in other words there's nothing really to point to - manually, and the global flag just catches everything it comes across?

borkdude08:09:19

One namespace compiles to many classes with unpredictable suffixes

Bart Kleijngeld08:09:45

Ahh, right. So if we upgrade to the master version of primitive-math which has a multi-segment namespace, we can point to it manually?

borkdude08:09:01

you don't need master, 1.0.0 has those multi-segment namespaces and if you use those rather than the single-segment one, you don't need to do anything manually

Bart Kleijngeld08:09:46

Weird, since 1.0.0 is the version being used.

Bart Kleijngeld08:09:15

[clj-easy/graal-build-time] WARN: Single segment package found for class: primitive_math__init.class. This class has no package and it will not be added to the result packages.
But the plugin still complains about the single segment package.

Bart Kleijngeld09:09:34

I think my level of understanding of the basics is insufficient. Lancaster does use 1.0.0 (the one you claim is multi-segment). Or is the single namespace segment still accessible in that version (and are you then saying that perhaps Lancaster still uses that)?

borkdude09:09:59

Yes it is. For backwards compatibility. You need to move manually to the multi-segment namespace, there is no magic here

Bart Kleijngeld09:09:34

Alright, I finally understand why we seemed to be talking past one another. Thanks for clarifying

👍 1
igrishaev09:09:20

Hi, can anyone give me a hint on charset for native image? When I run a binary file compiled, the default charset is US-ASCII, and all the non-english symbols sent to stdout/stderr appear as question marks. Is it possible to change the charset with an argument?

igrishaev09:09:51

I’m using a binary file compiled from Clojure in a cloud service where interaction goes through stdout (response) and stderr (logs). At the moment, I can only use english characters which is a bit inconvenient sometimes.

igrishaev09:09:29

Not yet, let me try…

igrishaev09:09:35

I have global :jvm-opts ["-Dfile.encoding=UTF-8"] in my project.clj file, and -H:+AddAllCharsets in the args. Still, printing something like “Иван” gives ???? in the console

borkdude09:09:26

Maybe you also have to provide that jvm option to native image during compilation

igrishaev09:09:26

and (Charset/defaultCharset) returns US-ASCII

igrishaev09:09:58

wow, -J-Dfile.encoding=UTF-8 had worked! Thanks!

👍 1