graalvm

Martynas Maciulevičius 2022-07-28T07:54:52.800739Z

How can I start compiling my JAR into GraalVM? I added :gen-class and wrapped my SecureRandom in delay but then I have to make the logger work and I use [com.fzakaria/slf4j-timbre "0.3.21"]+`[org.clojure/tools.logging "1.2.4"]` which isn't liked by the native-image compiler. So... should I change my logger or what? I think that it does some logging even during compilation time and it gets initialized so I'm not sure what to do. Maybe my logging is misconfigured? This is the error from GraalVM:

Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of com.github.fzakaria.slf4j.timbre.TimbreLoggerAdapter are allowed in the image heap as this class should be initialized at image runtime. Object has been initialized by the io.netty.channel.nio.AbstractNioChannel class initializer with a trace:
` I don't understand why that is a problem 🤔 This is my command: native-image -jar ./target/uberjar/app.jar --initialize-at-run-time=com.github.fzakaria.slf4j.timbre.TimbreLoggerAdapter --trace-object-instantiation=com.github.fzakaria.slf4j.timbre.TimbreLoggerAdapter

borkdude 2022-07-28T08:01:21.313119Z

@invertisment_clojuria If you see logging during compilation this means you have an expression like this:

(def foo (do (+ 1 2 3) (log "hello")))
either directly or via a function call on the top level.

Martynas Maciulevičius 2022-07-28T08:02:16.304059Z

But this is inside of a method fn. So it can be dynamic 🤔 Isn't it? Or does that mean that graalvm will load the log function and inline it in nasty ways and that's why it puts it onto the heap?

borkdude 2022-07-28T08:03:10.204439Z

this fn is then called on the top level

borkdude 2022-07-28T08:03:16.932809Z

no

borkdude 2022-07-28T08:03:42.430369Z

you don't see the logging if you compile your uberjar with clojure itself?

borkdude 2022-07-28T08:03:49.454309Z

I would expect the same to happen

Martynas Maciulevičius 2022-07-28T08:04:43.750839Z

Something triggers the log once during the build of uberjar (I think something loads netty and it logs one line). But almost all my functions that do logging are declared in top-level. So then do I need to make a workaround in native-image command?

borkdude 2022-07-28T08:05:27.200849Z

> Something triggers the log once during the build of uberjar Yes so this is why it happens during compilation of native image as well

borkdude 2022-07-28T08:05:41.576989Z

It's not about functions, it's about something that calls this function on the top level

Martynas Maciulevičius 2022-07-28T08:06:25.769079Z

Alright. I think it's some kind of a library that does this. I'll try to find out. This is the line that appears when I build uberjar.

22-07-28 08:06:03 _ INFO [org.eclipse.jetty.util.log:170] - Logging initialized @15374ms to org.eclipse.jetty.util.log.Slf4jLog

Martynas Maciulevičius 2022-07-28T08:34:11.802139Z

Found the culprit: https://github.com/eclipse/jetty.project/blob/cb127793e5d8b5c5730b964392a9a905ba49191d/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/KeyStoreScanner.java#L39 It's imported when jetty is imported. So the log message is triggered on the import.

Martynas Maciulevičius 2022-07-28T08:52:43.104449Z

https://github.com/ring-clojure/ring/issues/468

Matthew Davidson 2022-07-28T09:11:58.570769Z

Is anyone using byte-streams with Graal? I could use a hand if so.

borkdude 2022-07-28T09:26:12.996389Z

I don't think I do , but let me know your problems

Matthew Davidson 2022-07-28T09:32:41.996999Z

We deprecated the top-level byte-streams ns and copied everything lower down to clj-commons.byte-streams. Well, we just got a bug report related to an update that changed the lower ns but not the top-level ns. Rather than copy changes back for the indefinite future, and testing both, I’m considering using potemkin to import all the vars to the old ns, so they’re always in sync. The primary reason we deprecated the top-level ns was because it caused graal problems (clj-easy/graal problems, in particular). In theory, graal users requiring the clj-commons.byte-streams ns should be insulated from top-level ns changes. However, I don’t use Graal, and potemkin can do some weird things, so I was hoping to find someone to test it when ready, just to make sure.

borkdude 2022-07-28T09:34:05.803379Z

I'm aware of that top level ns move, I was one of the people who proposed that. If you use potemkin only in the top level ns, the nested ns won't have any problems with that

borkdude 2022-07-28T09:34:29.205949Z

but why not just maintain the nested ns and tell people to migrate?

borkdude 2022-07-28T09:34:48.627499Z

Imo the top level ns should not be edited anymore

Matthew Davidson 2022-07-28T09:35:17.131629Z

Because I got a bug report over it 😄

borkdude 2022-07-28T09:35:56.503489Z

but in response to the bug report, why not tell people: migrate to the nested ns first and we'll fix it there?

Matthew Davidson 2022-07-28T09:36:01.272899Z

It was kind of indirect, since the issue cropped up in some Aleph example code

borkdude 2022-07-28T09:36:18.885759Z

Update the example code too :)

Matthew Davidson 2022-07-28T09:36:47.055339Z

So it was a valid thing we needed to fix, but I figured, why not prevent this from ever being an issue?

borkdude 2022-07-28T09:37:11.266279Z

Because people should really be moving to the nested ns

borkdude 2022-07-28T09:37:21.104689Z

and not fixing issues in the top level ns will encourage them to do so

Matthew Davidson 2022-07-28T09:39:27.301949Z

True, true. I just don’t want to waste time on it, or cause users problems, if potemkin/import-vars can fix it all…of course potemkin is also a top-level ns, so that might require changes for graal as well. ¯\(ツ)

borkdude 2022-07-28T09:40:36.310839Z

My stance is: don't waste any energy on the deprecated ns and tell people to migrate, change the examples :)

Matthew Davidson 2022-07-28T09:41:59.200869Z

Fair. Maybe it won’t be a big issue.