So I am trying to migrate a spring mvc (sp4) application to spring-boot application but I want to take a "bottom up" approach since I already have my configuration files made/tested and I know they work I just want to convert to a barebones spring-boot-web application where my existing configs will work on an embedded tomcat server.
All the solutions I have read so far in the documentation take a "top down" approach where they suggest to import all the starter jars you need and @EnableAutoConfiguration
and "turn off" configs you don't need over time. I think this "top down" approach works great if you're starting from scratch but not if you're migrating an existing application.
Problem: That being said i'm trying to migrate my existing sp4 mvc app via a "bottom up" approach without @EnableAutoConfiguration
... but i'm having trouble creating a barebones spring-boot-web application with my existing configs.
My configuration:
that implements a WebApplicationInitializer and @Override(s) the startup method
public class FooWebAppWebApplicationInitializer implements WebApplicationInitializer {
public static final String SERVLET_NAME = "foo-web-app";
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(RootConfig.class);
// Manage the lifecycle of the root application context
servletContext.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
dispatcherContext.register(SpringMvcConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = servletContext.addServlet(SERVLET_NAME, new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
//Spring security config
FilterRegistration.Dynamic springSecurityFilterChain =
servletContext.addFilter(
"securityFilter", new DelegatingFilterProxy("springSecurityFilterChain")
);
springSecurityFilterChain.addMappingForServletNames(null, false, SERVLET_NAME);
servletContext.addFilter("hiddenHttpMethodFilter", HiddenHttpMethodFilter.class);
}
Note: With SpringMvcConfig.class
contains an @EnableWebMvc
annotation.
Note: no @Component
scanning is used... all beans are EXPLICITLY declared in config classes.
Spring Boot Runner:
@Configuration
public class SpringBootRunner {
public static void main(String[] args) {
//SpringApplicationBuilder sab = new SpringApplicationBuilder();
SpringApplication springApplication
= new SpringApplication(RootConfig.class,
SpringMvcConfig.class);
springApplication.run(args);
//SpringApplication.(SpringBootRunner.class, args);
}
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setPort(9000);
factory.setSessionTimeout(10, TimeUnit.MINUTES);
//factory.setErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html"));
return factory;
}
}
Maven pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.foo</groupId>
<artifactId>foo-web-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java-version>1.8</java-version>
</properties>
<dependencies>
//... omitted application specific dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
...
Things i've tried...
As the spring boot documentation states: Convert the existing
WebApplicationInitializer
->SpringBootServletInitializer
and copy/paste the contentstried passing the SpringBootServletInitializer to my runner (Result: server starts but my config was ignored)
tried
@Override
the configure method explicitly passing in the root / servlet context
.
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
application.sources(RootConfig.class);
application.child(SpringMvcConfig.class);
return application.sources(SpringBootServletInitializer.class);
}
that again resulted in the tomcat server starting but my config being ignored.
- Tried to pass the root and mvc configs directly to the SpringBootRunner resulted in... the configs loading in the logger but threw the following exception
.
Caused by: java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
at org.springframework.util.Assert.notNull(Assert.java:115) ~[spring-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
Question: Tried various other approaches still with no luck. Tired of guessing. I really couldn't find an example of what I am trying to achieve anywhere. Does anyone know of a sample project or know what runner/config I need to achieve my desired "bottom up" approach for a migration to spring boot?
I just want to migrate my existing sp4 mvc config to a barebones spring-boot-web app and enable boot starters 1 by 1 after running my existing unit/integration tests on each starter jar I am migrating to.