Cannot get production build to run using Spring Boot, Vaadin 24.7. We have set every possible property every possible way. Does not work. The problem appears to be in the vaadinBuildFrontend task. It builds DEV mode no matter what config. We even used the properties in the build commands and added them to the run script.
We have spent an enormous amount of time troubleshooting this. Vaadin seems broken.
Here is the error:
Jul 03, 2025 11:53:50 AM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class [com.vaadin.flow.spring.VaadinServletContextInitializer$CompositeServletContextListener]
java.lang.RuntimeException: Unable to initialize com.vaadin.flow.spring.VaadinServletContextInitializer$DevModeServletContextListener
at com.vaadin.flow.spring.VaadinServletContextInitializer$FailFastServletContextListener.contextInitialized(VaadinServletContextInitializer.java:206)
at com.vaadin.flow.spring.VaadinServletContextInitializer$CompositeServletContextListener.lambda$contextInitialized$0(VaadinServletContextInitializer.java:230)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at com.vaadin.flow.spring.VaadinServletContextInitializer$CompositeServletContextListener.contextInitialized(VaadinServletContextInitializer.java:230)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4044)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4474)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1193)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:749)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:772)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1193)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:749)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:203)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:412)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:870)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:438)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:128)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:107)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:517)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:219)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:193)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:167)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:621)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1362)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1351)
at com.extrospectre.web.Application.main(Application.java:65)
Caused by: java.lang.RuntimeException: no DevModeHandlerManager implementation found but but dev server enabled. Either disable by setting vaadin.frontend.hotdeploy=false (and run the build-frontend maven goal) or include the vaadin-dev-server dependency
at com.vaadin.flow.spring.VaadinServletContextInitializer$DevModeServletContextListener.failFastContextInitialized(VaadinServletContextInitializer.java:528)
at com.vaadin.flow.spring.VaadinServletContextInitializer$FailFastServletContextListener.contextInitialized(VaadinServletContextInitializer.java:202)
... 41 more
The production section does not do what its supposed to do. Taking that out makes bootRun work but that led to the next error:
Jul 03, 2025 12:20:07 PM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class [com.vaadin.flow.spring.VaadinServletContextInitializer$CompositeServletContextListener]
java.lang.RuntimeException: Unable to initialize com.vaadin.flow.spring.VaadinServletContextInitializer$DevModeServletContextListener
at com.vaadin.flow.spring.VaadinServletContextInitializer$FailFastServletContextListener.contextInitialized(VaadinServletContextInitializer.java:206)
at com.vaadin.flow.spring.VaadinServletContextInitializer$CompositeServletContextListener.lambda$contextInitialized$0(VaadinServletContextInitializer.java:230)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at com.vaadin.flow.spring.VaadinServletContextInitializer$CompositeServletContextListener.contextInitialized(VaadinServletContextInitializer.java:230)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4044)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4474)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1193)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:749)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:772)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1193)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:749)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:203)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:412)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:870)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:438)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:128)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:107)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:517)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:219)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:193)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:167)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:621)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1362)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1351)
at app.Application.main(Application.java:65)
Caused by: java.lang.IllegalStateException: Failed to determine project directory for dev mode. Directory '<path>\build\install\Website\bin' does not look like a Maven or Gradle project. Ensure that you have run the prepare-frontend Maven goal, which generates 'flow-build-info.json', prior to deploying your application
at com.vaadin.flow.server.AbstractConfiguration.getProjectFolder(AbstractConfiguration.java:238)
at com.vaadin.flow.server.AbstractConfiguration.getJavaResourceFolder(AbstractConfiguration.java:261)
at com.vaadin.base.devserver.startup.DevModeInitializer.initDevModeHandler(DevModeInitializer.java:229)
at com.vaadin.base.devserver.DevModeHandlerManagerImpl.initDevModeHandler(DevModeHandlerManagerImpl.java:106)
at com.vaadin.flow.spring.VaadinServletContextInitializer$DevModeServletContextListener.failFastContextInitialized(VaadinServletContextInitializer.java:593)
at com.vaadin.flow.spring.VaadinServletContextInitializer$FailFastServletContextListener.contextInitialized(VaadinServletContextInitializer.java:202)
... 41 more
The template project tells you to do this:
cd build/libs/
java -jar base-starter-spring-gradle*.jar
That will not work in a production deployed product. We need the shell script produced by the installDist task to work so the working dir is correct and other things. The spring start scripts still do not work even though bootRun does.
We are running the installDist task to create the install folder with scripts.
That Configuration block I showed at the top SHOULD work but does not. If you just follow that template project version, the bootRun works but the dev mode jars are still included, so not really working.
I’m not so familiar with Gradle, so I don’t really understand the posted configurations, but looking at the exception it seems vaadinBuildFrontend did not run (or did not run correctly). I guess you activate production mode by setting vaadin.productionMode=true in the build file or passing it to the command line.
Anyway, if you can provide an example project with your configuration, we can take a look and try to improve the plugin, if needed.
If you have any idea on how to make the plugin better, please create tickets on the Vaadin Flow repository. Of course, also code contributions are more than welcome.
Thank you. I will do that as soon as I can. The problem is that when you run the installed app via the Spring start scripts, it thinks its still in dev mode. These scripts are created by the Gradle installDist task. We already have to customize those scripts in our build.gradle because Spring expects the application.properties to be in the current working dir, which is bad for an installed application. The vaadin-dev and vaadin-dev-bundle jars keep getting deployed despite building for production. We’ve tried manually removing them but still get errors, the last one I posted. Its not switching to production mode correctly when built with Gradle.
That code is necessary because Spring expects the application.properties to be in the current dir, which would be the bin dir, and that is not appropriate for a deployed product. So we modify the script. The gradle installDist which creates this script needs to be enhanced to provide an easier way to tell Spring where that file is located.
There were a few other cosmetic things as well.
The Spring logging led us in the wrong direction as usual. That’s the penalty for using Spring.