From 500c8e9221eee8b013e2efbbcb05279d40afc3d6 Mon Sep 17 00:00:00 2001 From: Marco Collovati Date: Wed, 14 Sep 2022 12:44:55 +0200 Subject: [PATCH] fix: set load-on-startup for automatically registered Vaadin servlets (#84) * fix: set load-on-startup for automatically registered Vaadin servlet When using Vite, DevModeInitializer blocks dev-server startup until a VaadinServlet is deployed because it needs to get the servlet path to use. If the container lazily loads servlets, Vite will not start until the first HTTP request for the Vaadin servlet is received. This change sets load-on-startup feature for all Vaadin Servlet registered by the extension, to ensure that Vite is loaded at the startup of the Web application. A warning message is shown for custom Vaadin servlets that do not set loadOnStartup on WebServlet annotation. Part of vaadin/flow#14479 * Fixes from code review Co-authored-by: marcin <106965834+MarcinVaadin@users.noreply.github.com> Co-authored-by: marcin <106965834+MarcinVaadin@users.noreply.github.com> --- .../deployment/VaadinQuarkusProcessor.java | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/deployment/src/main/java/com/vaadin/quarkus/deployment/VaadinQuarkusProcessor.java b/deployment/src/main/java/com/vaadin/quarkus/deployment/VaadinQuarkusProcessor.java index a896026..7fc141b 100644 --- a/deployment/src/main/java/com/vaadin/quarkus/deployment/VaadinQuarkusProcessor.java +++ b/deployment/src/main/java/com/vaadin/quarkus/deployment/VaadinQuarkusProcessor.java @@ -17,6 +17,7 @@ import javax.servlet.annotation.WebServlet; +import java.util.ArrayList; import java.util.Collection; import java.util.Objects; import java.util.Optional; @@ -68,7 +69,8 @@ class VaadinQuarkusProcessor { - private static final Logger LOG = LoggerFactory.getLogger(VaadinQuarkusProcessor.class); + private static final Logger LOG = LoggerFactory + .getLogger(VaadinQuarkusProcessor.class); private static final String FEATURE = "vaadin-quarkus"; @@ -111,7 +113,7 @@ void mapVaadinServletPaths(final BeanArchiveIndexBuildItem beanArchiveIndex, // Collect all VaadinServlet instances and remove QuarkusVaadinServlet // and VaadinServlet from the list. - final Collection vaadinServlets = indexView + Collection vaadinServlets = indexView .getAllKnownSubclasses( DotName.createSimple(VaadinServlet.class.getName())) .stream() @@ -121,14 +123,16 @@ void mapVaadinServletPaths(final BeanArchiveIndexBuildItem beanArchiveIndex, .equals(VaadinServlet.class.getName())) .collect(Collectors.toList()); - // If no VaadinServlet instances found register QuarkusVaadinServlet + // Register VaadinServlet instances annotated with @WebServlet + vaadinServlets = registerUserServlets(servletProducer, vaadinServlets); + // If no annotated VaadinServlet instances is registered, register + // QuarkusVaadinServlet if (vaadinServlets.isEmpty()) { servletProducer.produce(ServletBuildItem .builder(QuarkusVaadinServlet.class.getName(), QuarkusVaadinServlet.class.getName()) - .addMapping("/*").setAsyncSupported(true).build()); - } else { - registerUserServlets(servletProducer, vaadinServlets); + .addMapping("/*").setAsyncSupported(true) + .setLoadOnStartup(1).build()); } } @@ -224,15 +228,20 @@ void setupPush(ServletDeploymentManagerBuildItem deployment, deployment.getDeploymentManager()), 120)); } - private void registerUserServlets( + private Collection registerUserServlets( BuildProducer servletProducer, Collection vaadinServlets) { + Collection registeredServlets = new ArrayList<>( + vaadinServlets); // TODO: check that we don't register 2 of the same mapping for (ClassInfo info : vaadinServlets) { final AnnotationInstance webServletInstance = info.classAnnotation( DotName.createSimple(WebServlet.class.getName())); if (webServletInstance == null) { - LOG.warn("Found unexpected {} extends VaadinServlet without @WebServlet, skipping", info.name()); + LOG.warn( + "Found unexpected {} extends VaadinServlet without @WebServlet, skipping", + info.name()); + registeredServlets.remove(info); continue; } @@ -240,6 +249,9 @@ private void registerUserServlets( .ofNullable(webServletInstance.value("name")) .map(AnnotationValue::asString) .orElse(info.name().toString()); + int loadOnStartup = Optional + .ofNullable(webServletInstance.value("loadOnStartup")) + .map(AnnotationValue::asInt).orElse(-1); final ServletBuildItem.Builder servletBuildItem = ServletBuildItem .builder(servletName, info.name().toString()); @@ -251,9 +263,18 @@ private void registerUserServlets( addWebInitParameters(webServletInstance, servletBuildItem); setAsyncSupportedIfDefined(webServletInstance, servletBuildItem); - + servletBuildItem + .setLoadOnStartup(loadOnStartup > 0 ? loadOnStartup : 1); + if (loadOnStartup < 1) { + LOG.warn( + "Vaadin Servlet needs to be eagerly loaded by setting load-on-startup to be greater than 0. " + + "Current value for '{}' is '{}', so it will be forced to '1'. " + + "Please set 'loadOnStartup' attribute on @WebServlet annotation to a value greater than 0.", + servletName, loadOnStartup); + } servletProducer.produce(servletBuildItem.build()); } + return registeredServlets; } private void addWebInitParameters(AnnotationInstance webServletInstance,