Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Graal Native Image #20

Open
2 tasks
tusharmath opened this issue Mar 12, 2021 · 16 comments
Open
2 tasks

Support Graal Native Image #20

tusharmath opened this issue Mar 12, 2021 · 16 comments
Labels
information maintenance Chore or Maintenance tasks

Comments

@tusharmath
Copy link
Collaborator

tusharmath commented Mar 12, 2021

The resulting program has faster startup time and lower runtime memory overhead compared to a JVM

https://www.graalvm.org/reference-manual/native-image

  • Add documentation about how to get started with GraalVM and ZIO Http
  • Add a CI check to ensure all builds compile on GraalVM.
@jamesward
Copy link
Contributor

Here is a sample that has the required config: https://github.com/jamesward/hello-zio-http/tree/graalvm

@tusharmath tusharmath added the enhancement New feature or request label Mar 26, 2021
@kitlangton
Copy link
Member

Unfortunately, that config isn't working for me in my project. Perhaps things changed with the versions. Or perhaps I'm doing it wrong. :'(

I can't seem to avoid:

 io.netty.util.AbstractReferenceCounted the class was requested to be initialized at run time (from the command line). io.netty.util.AbstractReferenceCounted has been initialized without the native-image initialization instrumentation and the stack trace can't be tracked. Try avoiding to initialize the class that caused initialization of io.netty.util.AbstractReferenceCounted
io.netty.channel.DefaultFileRegion the class was requested to be initialized at run time (subtype of io.netty.util.AbstractReferenceCounted). io.netty.channel.DefaultFileRegion has been initialized without the native-image initialization instrumentation and the stack trace can't be tracked. Try avoiding to initialize the class that caused initialization of io.netty.channel.DefaultFileRegion

@jamesward
Copy link
Contributor

I bumped stuff up to the latest:
jamesward/hello-zio-http@4d29152

Note the GraalVM configs in the build.sbt which are for Netty:
https://github.com/jamesward/hello-zio-http/blob/graalvm/build.sbt#L97-L108

Hopefully that helps.

@reibitto
Copy link

For Linux, the config @jamesward posted worked as is for me. When I tried to build a native image for macOS (without Docker or anything like that), I got the same errors @kitlangton was seeing.

I was able to get it working by adding the following to the config that's already there:

"--initialize-at-run-time=io.netty.util.AbstractReferenceCounted",
"--initialize-at-run-time=io.netty.channel.kqueue.KQueue",

and then you also have to remove --static on macOS, otherwise you'll get:

com.oracle.svm.core.util.UserError$UserException: DARWIN does not support building static executable images.

After that it worked. Startup is instantaneous 🙂

@jamesward
Copy link
Contributor

Nice @reibitto!

@reibitto
Copy link

Oh wow, I also tested this on native Windows and it worked! Setting up the Windows environment for Graal native-image is a little tricky (refer to this), but I didn't have to make any changes to the hello-zio-http project itself. I was not expecting that 😅

Unsurprisingly it also works with WSL.

@kitlangton
Copy link
Member

<3 <3 <3 Thank you all so much. I lost an embarrassing number of hours to this yesterday. Excited to try this out :)

@jamesward
Copy link
Contributor

@kitlangton You've made it through the Native Image initiation rites! You should see my scars.

@kitlangton
Copy link
Member

🤖 Native... Image... Ready

😭

@kitlangton
Copy link
Member

Never has it felt so good to be startled by those words.

@reibitto
Copy link

Oh, that makes sense. You were using sbt-native-image, not sbt-native-packager, right? sbt-native-image doesn't support Docker.

@kitlangton
Copy link
Member

Oh, that makes sense. You were using sbt-native-image, not sbt-native-packager, right? sbt-native-image doesn't support Docker.

Yeah! Your guess was correct (in the zio-http discord) that I'm using it as a local dev server for this https://twitter.com/kitlangton/status/1396918103414427648. Main goal is instant start-up.

@tusharmath tusharmath added maintenance Chore or Maintenance tasks and removed enhancement New feature or request labels Jun 3, 2021
@ithinkicancode
Copy link

Can anyone make native-image compile then run successfully when including quill-jdbc-zio? After I added quill-jdbc-zio (I was able to isolate the problem to just this lib in my project), I had to add a lot of more --initialize-at-run-time entries. Then even when it succeeded building the image, my app crashed upon launch with this error message:

java.lang.NoClassDefFoundError: Could not initialize class io.netty.buffer.ByteBufAllocator

@jamesward @reibitto If you can look into this, I'd greatly appropriated. I just wish GraalVM's dev experience is much better than trial'n'errors.
I apologize for asking here @tusharmath... it's not often to get James and Reibitto in the same thread, and I know both have good experience with Graal. Thanks in advance.

@reibitto
Copy link

@ithinkicancode That's weird because I don't think quill even uses netty. If it's complaining about netty, then the problem might be coming from zio-http. But you're saying it only happens when you add quill-jdbc-zio to the project?

I'm actually going to try using native-image in one of my projects which happens to also use quill, so I might learn something in that process. If I manage to do it successfully I can let you know. If I forget, then it's this project. I need a little time though because I have to finish swapping out akka-http for zio-http first.

@joprice
Copy link

joprice commented Jul 11, 2021

At least one of the async drivers uses netty: https://github.com/postgresql-async/postgresql-async

@carlosedp
Copy link

As a followup to this issue, according to scala/scala3#13985, the main LazyVal problem is fixed but its still not released (apparently will be on Scala 3.3) and then it will require that all libs are built with this new compiler.

Another option is using scala-cli package command which does the bytecode manipulation as mentioned in the issue (scala/scala3#13985 (comment)) automatically.

I found a couple more flags required to be initialized and added it to a sample repo at https://github.com/carlosedp/ziohttp. It has a script to package the application to a native-image.

For the curious, the bytecode manip code is at https://github.com/VirtusLab/scala-cli/tree/main/modules/scala3-graal/src/main/scala/scala/cli/graal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
information maintenance Chore or Maintenance tasks
Projects
None yet
Development

No branches or pull requests

8 participants