It seems that in war (boot war) deployment it is called at least twice as for other kind of deploy like boot jar (Spring; it seems executed just once).

There are two different ways in which VaadinServiceInitListener implementations are picked up: based on an entry in /META-INF/services/com.vaadin.flow.server.VaadinServiceInitListener, and based on discovered Spring (or CDI) beans that implement the interface. If a class is discoverable in both ways, then it will be used twice.

If you know that the application will always be used with Spring, then you can remove the /META-INF/services entry. If Spring isn’t certain, then you can instead prevent the class from being used as a Spring bean by e.g. removing the @Component or @SpringComponent annotation.

This behavior can indeed be quite confusing, so I created a ticket about ignoring the “additional” occurrence:

Dear Leif,

There is no annotation in use.

My next guess then would be that that happens is that there multiple VaadinServlet instances are deployed. Since each servlet creates its own VaadinService, there will also be multiple events.

The most likely explanation for why there would be multiple servlets is if there is a VaadinServlet subclass annotated with @WebServlet on the classpath (or defined through web.xml, or a custom @WebListener that programmatically deploys a servlet). Such servlets are ignored with the embedded servlet container used through Spring Boot but they are picked up when a war file is deployed to a conventional servlet container.

You can find out whether this is the case by making the servlet init listener print out some info about the servlet that it belongs to:

VaadinServletService servletService = (VaadinServletService) event.getSource();
VaadinServlet servlet = servletService.getServlet();
System.out.println("Service init for " + servlet.getServletName() + " of type " + servlet.getClass().getName() + " with id " + System.identityHashCode(servlet));

If the duplicate call is about the devModeInitilaizer getting executed twice for a war deployed to for instance Tomcat
the duplicate execution is due to the fact that tomcat will run com.vaadin.flow.server.startup.DevModeInitializer due to META-INF/services/javax.servlet.ServletContainerInitializer and then Spring will run the initDevModeHandler method from the VaadinServletContextInitializer::DevModeServletContextListener (that is there for SpringBoot as it else doesn’t run the expected servlet initializers) as it doesn’t know that dev mode handle was initialized already.

  • Mikael