vaadin / quarkus

An extension to Quarkus to support Vaadin Flow
Apache License 2.0
28 stars 3 forks source link

Atmosphere dependency makes native image build fail #157

Open mcollovati opened 1 month ago

mcollovati commented 1 month ago

The Atmosphere version currently in use (3.0.5) is built upon Servlet 5 API. However, both Flow and Quarkus HTTP depend on Servlet 6, that removes some deprecated APIs.

Atmosphere code is referencing those removed APIs, even though they are not invoked at runtime, so running the application in both development and production mode works fine.

Unfortunately, the presence of those removed API makes the native compilation fail.

One way to resolve the issue is to provide a Servlet 6 compatible version of Vaadin's fork of atmosphere.

Fixing the Servlet API issue is still not enough to produce a native image: Atmosphere gets initialized by a ServletContainerInitializer or by PushRequestHandler, that are executed at STATIC_INIT phase by the Quarkus undertow extension. This causes GraalVM to complain about threads started by Atmosphere during this phase (Error: Detected a started Thread in the image heap. Thread name: Atmosphere-Scheduler-0 ...).

This issue is usually fixed by adding a --init-at-runtime instruction, listing the classes that are causing the threads to start. For Vaadin add-on this does not work because the classes that initialize the Atmosphere framework are executed at STATIC_INIT phase (how mentioned before), conflicting with the --init-at-runtime instruction. The only way to get rid of this clash would be to add the --init-at-runtime=io.quarkus.runner.ApplicationImpl instruction, that basically means loosing all performance optimization. In addition, even if this hack makes the native compilation succeed, then the native executable immediately fails when launched.

We should find a way to prevent the Atmosphere initialization at STATIC_INIT (e.g. remove the ServletContainerInitializer during native compilation and prevent PushRequestHandler from starting Atmosphere, by changing it or using some byte-code enhancement) and postpone it at STATIC_RUNTIME phase.