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

Graalvm support for Bolt for Java #1009

Closed
1 of 6 tasks
nikosk686 opened this issue Jul 5, 2022 · 10 comments
Closed
1 of 6 tasks

Graalvm support for Bolt for Java #1009

nikosk686 opened this issue Jul 5, 2022 · 10 comments
Labels
question M-T: User needs support to use the project

Comments

@nikosk686
Copy link

Category

  • bolt (Bolt for Java)
  • bolt-{sub modules} (Bolt for Java - optional modules)
  • slack-api-client (Slack API Clients)
  • slack-api-model (Slack API Data Models)
  • slack-api-*-kotlin-extension (Kotlin Extensions for Slack API Clients)
  • slack-app-backend (The primitive layer of Bolt for Java)

Requirements

I have a small POC where I use Quarkus and com.slack.api:bolt:1.22.3.
I have managed to build the project and produce a native executable,
I had to add the following configuration

quarkus.native.additional-build-args=--initialize-at-run-time=com.slack.api.Slack,--initialize-at-run-time=com.slack.api.SlackConfig,--initialize-at-run-time=com.slack.api.scim.SCIMConfig,--initialize-at-run-time=com.slack.api.token_rotation.TokenRotator,--initialize-at-run-time=com.slack.api.audit.AuditConfig,--initialize-at-run-time=com.slack.api.methods.MethodsConfig

in order to achieve it.

However when I try to execute a call to MethodsClient.chatPostMessage I am getting the following error

 ERROR [org.jbo.res.rea.com.cor.AbstractResteasyReactiveContext] (vert.x-eventloop-thread-0) Request failed: com.oracle.svm.core.jdk.UnsupportedFeatureError: Code that was considered unreachable by closed-world analysis was reached.
        at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:89)
        at com.oracle.svm.core.snippets.SnippetRuntime.unsupportedFeature(SnippetRuntime.java:175)
        at java.lang.reflect.Method.invoke(Method.java:568)
        at com.google.gson.internal.UnsafeAllocator$1.newInstance(UnsafeAllocator.java:50)
        at com.google.gson.internal.ConstructorConstructor$16.construct(ConstructorConstructor.java:272)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:211)
        at com.google.gson.Gson.fromJson(Gson.java:991)
        at com.google.gson.Gson.fromJson(Gson.java:956)
        at com.google.gson.Gson.fromJson(Gson.java:905)
        at com.google.gson.Gson.fromJson(Gson.java:876)
        at com.slack.api.methods.impl.MethodsClientImpl.parseJsonResponseAndRunListeners(MethodsClientImpl.java:3239)
        at com.slack.api.methods.impl.MethodsClientImpl.parseJsonResponseAndRunListeners(MethodsClientImpl.java:3226)
        at com.slack.api.methods.impl.TeamIdCache.lambda$lookupOrResolve$0(TeamIdCache.java:44)
        at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
        at com.slack.api.methods.impl.TeamIdCache.lookupOrResolve(TeamIdCache.java:67)
        at com.slack.api.methods.impl.TeamIdCache.lookupOrResolve(TeamIdCache.java:40)
        at com.slack.api.methods.impl.MethodsClientImpl.postFormWithTokenAndParseResponse(MethodsClientImpl.java:3124)
        at com.slack.api.methods.impl.MethodsClientImpl.chatPostMessage(MethodsClientImpl.java:1497)
        at com.slack.api.methods.impl.MethodsClientImpl.chatPostMessage(MethodsClientImpl.java:1502)
        at com.slack.api.methods.BeanConfiguration_ProducerMethod_slackClient_b716f310108cdb64e1cf609cdebc303aa904c176_ClientProxy.chatPostMessage(Unknown Source)
        at com.tymit.ExampleResource.postMessage(ExampleResource.java:27)
        at com.tymit.ExampleResource$quarkusrestinvoker$postMessage_819d25448cb79a900296f7c48403c34ec62c2530.invoke(Unknown Source)
        at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
        at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:108)
        at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:141)
        at org.jboss.resteasy.reactive.server.vertx.VertxResteasyReactiveRequestContext$1$1.handle(VertxResteasyReactiveRequestContext.java:74)
        at org.jboss.resteasy.reactive.server.vertx.VertxResteasyReactiveRequestContext$1$1.handle(VertxResteasyReactiveRequestContext.java:71)
        at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:100)
        at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:63)
        at io.vertx.core.impl.EventLoopContext.lambda$runOnContext$0(EventLoopContext.java:38)
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:833)
        at com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:704)
        at com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:202)

Are there any plans for supporting native builds any time soon?
Thanks

@WilliamBergamin WilliamBergamin added question M-T: User needs support to use the project and removed untriaged labels Jul 5, 2022
@WilliamBergamin
Copy link
Contributor

Hi @nikosk686 thanks for writing in!

Currently we do not support quarkus native builds, the recommended way uses the jvm approach.

To my knowledge this feature has not been brought up by the team, currently there is no timeline to support it.
I will bring it up as a potential new feature!

@seratch
Copy link
Member

seratch commented Jul 5, 2022

@nikosk686
This SDK depends on gson, okhttp, and slf4j-api. If all of these dependencies are available for GraalVM apps in the future, we may be able to support the native build too. However, I don't expect gson to be available for GraalVM as it relies reflection APIs (this is the cause of the error you encountered). I haven't thoroughly checked other potential errors but there may be some others apart from gson internals.

As @WilliamBergamin mentioned, we don't have any timeline for this and our recommendation is to go with the JavaVM builds.

@seratch
Copy link
Member

seratch commented Jul 6, 2022

@nikosk686 Thanks for your 👍 reactions. Since we, this project maintainers, do not have any further actions for this issue in the short term, let us close this issue now. If it is possible to support GraalVM in the future, we may consider working on it.

@achugr
Copy link

achugr commented Feb 20, 2023

Hello!
GraalVM support looks very useful for cloud deployments, as Slack webhook timeout is 3 seconds and from what I tried with cloud run, an elementary JVM app that accepts an event from Slack and publishes it to cloud task starts in 5+ seconds. Cloud run timeout is 10 seconds, so the app gets a request, but Slack displays an error in the UI and the user most probably would like to re-attempt which is quite a bad UX for the integration. With GraalVM the same app starts within 1.5 seconds, which is acceptable.

Regarding okhttp and slf4j-api (tried backed by logback) there are not many problems, just a fixed amount of settings for GraalVM, still annoying, but quite a limited scope.

With Gson it's different, because of the following reasons:

  1. Many data transfer objects using Gson should be listed in the reflections config of GraalVM.
  2. If you miss something you'll get issues just at runtime on the transfer object serialization/deserialization, which could sometimes happen unexpectedly and after a long time running with no issues, depending on usage.

What do you think about using an approach used in Quarkus, when you explicitly state that some classes need to be registered for reflection?
Later on, in the build step, it allows to build a configuration for GraalVM.

Currently, there is a Lombok's @Data annotation on data transfer objects, but it can't be used as a marker as it has RetentionPolicy.SOURCE.

It looks like at a reasonably low cost (by adding the annotation to data transfer objects), it is possible to make GraalVM usage more smooth.

@fnobilia
Copy link

Hello team! Is there any update on GraalVM support? As @achugr said, there are lots of benefits in running in native mode.

@seratch
Copy link
Member

seratch commented Jul 24, 2023

@achugr @fnobilia, thank you for your comments. Technically, it might already be possible to add GraalVM support in some way, but we don't have plans to work on it in the short term. I understand the benefits of native builds, especially for the use cases you've mentioned. However, we have other priorities to focus on, and the number of GraalVM users seems significantly smaller in comparison to JavaVM users.

We may revisit this in the long run depending on the popularity of GraalVM and industry trends, but right now it's not the best timing for us.

@markchang-st
Copy link

Are there any updates on adding GraalVM support? Thanks

@seratch
Copy link
Member

seratch commented Apr 4, 2024

We currently have no plans for this, and that's expected to remain the same for at least the next few years.

@achugr
Copy link

achugr commented Apr 5, 2024

A bit off-topic, but it's worth mentioning as one of the potential solutions to the problem of slow startups, which are crucial in serverless environments. You could try CRaC. Here's an article about how to configure it. I haven't used CRaC myself yet, but I have tried a native build. In terms of configuration effort, CRaC seems even simpler than a native build, and I hope it will become trivial once it is supported through buildpacks.

@markchang-st
Copy link

A bit off-topic, but it's worth mentioning as one of the potential solutions to the problem of slow startups, which are crucial in serverless environments. You could try CRaC. Here's an article about how to configure it. I haven't used CRaC myself yet, but I have tried a native build. In terms of configuration effort, CRaC seems even simpler than a native build, and I hope it will become trivial once it is supported through buildpacks.

thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question M-T: User needs support to use the project
Projects
None yet
Development

No branches or pull requests

6 participants