mvysny/vaadin-boot

Native

mvysny opened this issue · 9 comments

mvysny commented

Native is cool these days. Add support for building with Graalvm; there's a Gradle plugin to build for native. Jetty and class auto discovery needs to be figured out.

mvysny commented

I've installed GraalVM and went through the tutorial at https://graalvm.github.io/native-build-tools/latest/gradle-plugin-quickstart.html - everything worked well.

Tried the same steps (agent+metadataCopy+nativeCompile) on https://github.com/mvysny/vaadin-boot-example-gradle, but unfortunately I'm getting

java.lang.NullPointerException
        at com.vaadin.flow.server.VaadinServlet.serveStaticOrWebJarRequest(VaadinServlet.java:431)
        at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:386)
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:587)
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764)
        at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1665)
        at org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:170)
        at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
        at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:527)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)

which means that VaadinServlet.staticFileHandler is null, which means that VaadinServlet.init() wasn't called. The startup time is instantaneous though - 17ms - which looks really promising.

I've tried to add the [Lorg.eclipse.jetty.servlet.ServletMapping; mapping as per https://javalin.io/2018/09/27/javalin-graalvm-example.html , didn't help. The tutorial looks old so it's probably of no value now. Maybe an updated tutorial of javalin+graalvm could also help.

I'm compiling Vaadin dev mode to native atm which is kind of dumb. I'll try the same thing but with prod mode.

I wonder whether GraalVM is actually compatible with Jetty's classpath scanning. Will study more. Perhaps an up-to-date jetty+graalvm article could help tremendously.

mvysny commented

Unfortunately the production build fails with the same exception.

Further things to check out:

mvysny commented

Debugged VaadinServlet in native a bit (by introducing my own MyServlet which extends VaadinServlet, and adding a bunch of stdout statements), found interesting info. VaadinServlet.init() actually does get called, however it soon bails out and does nothing, because Lookup is null. According to https://mvysny.github.io/vaadin-lookup-vs-instantiator/ that means that LookupServletContainerInitializer is not called, which means that Jetty classpath autodiscovery isn't working properly.

mvysny commented

Interesting related ticket which suggests that there might be some limitation in Jetty's classpath scanning: mvysny/vaadin-boot-example-maven#1

mvysny commented

Could the Quick start be the solution? #11

mvysny commented

Yup, QuickStart should help. Blocked by #11

mvysny commented

When running the native binary, QuickStart fails with

2023-03-16 13:32:47.747 [main] WARN org.eclipse.jetty.webapp.WebAppContext - Failed startup of context o.e.j.w.WebAppContext@1da6646c{/,resource:/webapp,STOPPED}{resource:/webapp}
java.lang.IllegalStateException: Bad Quickstart location
	at org.eclipse.jetty.quickstart.QuickStartConfiguration.preConfigure(QuickStartConfiguration.java:95)
	at org.eclipse.jetty.webapp.Configurations.preConfigure(Configurations.java:496)
	at org.eclipse.jetty.webapp.WebAppContext.preConfigure(WebAppContext.java:510)
mvysny commented

The reason for that is that context.getBaseResource() resolves to resource:/webapp of type URLResource; both URLResource.isDirectory() and URLResource.exists() return false. I've patched QuickStartConfiguration:94 and commented out the check. I've also passed in the path to quickstart-web.xml as ctx.setAttribute(QuickStartConfiguration.QUICKSTART_WEB_XML, new PathResource(new File("src/main/resources/webapp/WEB-INF/quickstart-web.xml")));, and now the native mode works.

I'll polish the native mode, document, file a feature request at Jetty.