Vaadin Flow with Spring MVC in a fat jar

I am trying to package Flow and Spring MVC into a Spring Boot runnable jar (i.e. I intend to start my app with java -jar).
I am aware of the [example in the docs]
(https://vaadin.com/docs/v10/flow/spring/tutorial-spring-basic-mvc.html) which shows how to setup Vaadin Flow with Spring MVC. However, this doesn’t seem to work when packaging the application into a jar with Spring Boot’s embedded Tomcat. The WebApplicationInitializer is the problem here. I cannot use it with Spring Boot in an embedded Tomcat. However, something needs to run to register Vaadin’s SpringServlet as the dispatcher. This is [expected behaviour]
(https://github.com/spring-projects/spring-boot/issues/522) when using Spring Boot in this way. One has to use the ServletContextInitializer instead of WebApplicationInitializer.

So, I modified the example to

public class AppContextInitializer implements ServletContextInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        registerConfiguration(context);
        servletContext.addListener(new ContextLoaderListener(context));

        ServletRegistration.Dynamic registration = servletContext
                .addServlet("dispatcher", new SpringServlet(context));
        registration.setLoadOnStartup(1);
        registration.addMapping("/*");
    }

    private void registerConfiguration(
            AnnotationConfigWebApplicationContext context) {
        // register your configuration classes here
    }

}

But now, if I run with java -jar the embedded Tomcat is unable to start up:
java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
It seems Spring is trying to add additional ContextLoader definitions. However, I need to add mine, as the SpringServlet is required as the dispatcher.

Is there a way to achieve a fat jar with Spring Boot, combining Spring MVC and Vaadin Flow?
Do you have an example putting Vaadin Flow and Spring MVC into a Spring Boot fat jar?
If not, could you give confirmation that it isn’t currently possible (or rather easily possible) so I can stop trying and chose another way? :slight_smile:

Thanks.

Hi Jonas,

There are currently also other issues preventing proper usage of Flow with Spring Boot (jar packaging), related to templates and production transpilation. We are currently working on those. We should definitely look into this at the same time.

Could you create an issue about this to https://github.com/vaadin/spring ? And maybe share some example project with us or did you just directly change the linked example into jar packaging? Also if you would like to help and test the snapshot builds, I can let you know when we have snapshot builds available with related fixes.

cheers,
matti

Hi.

Currently Flow probably won’t play nice when run from a Spring-boot .jar
but there are open Pull Requests that should fix packaging and running flow
from a spring-boot fat jar.

I can’t directly promise Flow+Spring MVC works after these changes as I have not tested this yet.
I’ll test and get back to you.

  • Mikael