Migrates a Spring MVC application to Spring Boot, converting XML config to auto-configuration, restructuring the project, and replacing container deployment with embedded. Use when modernizing a legacy Spring app, when moving off a standalone servlet container, or when the user has web.xml and wants application.yml.
Install with Tessl CLI
npx tessl i github:santosomar/general-secure-coding-agent-skills --skill spring-mvc-to-boot-migrator97
Quality
96%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Spring Boot is Spring MVC with conventions, embedded server, and auto-configuration. The migration isn't a rewrite — it's deleting XML and letting Boot infer it.
| Concern | Spring MVC (classic) | Spring Boot | Migration effort |
|---|---|---|---|
@Controller classes | @Controller, @RequestMapping | Same — unchanged | Zero |
@Service, @Repository | Same annotations | Same — unchanged | Zero |
| Bean wiring (XML) | <bean id=... class=...> | @Configuration + @Bean, or just @Component | High — this is the work |
| DispatcherServlet setup | web.xml | Auto-configured — delete it | Delete |
| Server | Deploy WAR to Tomcat | Embedded Tomcat — java -jar | pom.xml change |
| Properties | Multiple .properties via <context:property-placeholder> | application.yml with profiles | Consolidate |
| View resolver | <bean class="InternalResourceViewResolver"> | spring.mvc.view.prefix=... property | One-liner |
| Static resources | <mvc:resources mapping=...> | /static, /public auto-served | Move files |
Boot can coexist with XML config. Migrate incrementally:
@Configuration. Test. Repeat.web.xml once DispatcherServlet XML config is gone.Maven:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.x.x</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Keep existing deps; remove spring-webmvc, spring-context — the starter brings them -->
</dependencies>Remove explicit spring-* versions — let the parent BOM manage them. Version conflicts here are → dependency-resolver territory.
@SpringBootApplication
@ImportResource("classpath:applicationContext.xml") // bridge — delete later
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}@ImportResource lets Boot load your old XML. App runs under Boot with zero config migrated. Verify everything works before touching XML.
XML:
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="url" value="${db.url}"/>
<property name="username" value="${db.user}"/>
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource"/>
</bean>Boot — option A: explicit @Configuration:
@Configuration
public class DatabaseConfig {
@Bean
public DataSource dataSource(@Value("${db.url}") String url,
@Value("${db.user}") String user) {
BasicDataSource ds = new BasicDataSource();
ds.setUrl(url);
ds.setUsername(user);
return ds;
}
// txManager — Boot auto-configures DataSourceTransactionManager if a DataSource bean exists. DELETE.
}Boot — option B: auto-config (preferred when it applies):
# application.yml
spring:
datasource:
url: ${DB_URL}
username: ${DB_USER}No Java at all. spring-boot-starter-jdbc sees these properties, auto-configures Hikari (not DBCP — behavior change, flag it).
| XML | Boot |
|---|---|
<context:component-scan base-package=...> | @SpringBootApplication scans its own package + subpackages. If your packages are elsewhere: @ComponentScan(basePackages=...) |
<mvc:annotation-driven/> | Auto — delete |
<mvc:resources mapping="/static/**" location="/assets/"/> | Move files to src/main/resources/static/ |
<bean class="...ViewResolver"> | spring.mvc.view.prefix / .suffix properties |
<tx:annotation-driven/> | Auto — @Transactional just works |
<context:property-placeholder location=...> | application.yml + @Value or @ConfigurationProperties |
Filters in web.xml | @Bean FilterRegistrationBean<YourFilter> or just @Component on the filter |
Servlets in web.xml | @Bean ServletRegistrationBean<...> |
Once every <bean> is migrated: delete @ImportResource, delete applicationContext.xml, delete web.xml. Run tests.
| Gotcha | Symptom | Fix |
|---|---|---|
| Package layout | Beans not found | @SpringBootApplication scans its own package down — move main class up, or add @ComponentScan |
| Auto-config conflict | Two DataSource beans | Your XML defined one, Boot auto-configured another. @Primary, or exclude the auto-config: @SpringBootApplication(exclude=DataSourceAutoConfiguration.class) |
| Connection pool switch | Different perf characteristics | Boot defaults to Hikari. If you need DBCP, declare it explicitly. |
| Context path | URLs all 404 | Was /myapp in the servlet container; now /. Set server.servlet.context-path=/myapp or fix your links. |
| JSP | Whitelabel error page | JSP + embedded Tomcat is fiddly — spring-boot-starter-tomcat provided scope, tomcat-embed-jasper, and keep WAR packaging. Or migrate to Thymeleaf. |
@ImportResource exists so you can do it a bean at a time.javax.* → jakarta.*). Do MVC → Boot 2, then Boot 2 → 3.## Current state
Spring version: <x>
Config style: <XML | JavaConfig | mixed>
Packaging: <WAR on <container>>
## Target
Boot version: <x>
Packaging: <executable JAR>
## Migration steps
| Step | XML removed | Java/YAML added | Test checkpoint |
| ---- | ----------- | --------------- | --------------- |
## Behavior changes
<connection pool, context path, anything auto-config does differently — FLAG THESE>
## Files
### pom.xml (diff)
### Application.java (new)
### application.yml (new)
### Deleted: <web.xml, applicationContext.xml, ...>47d56bb
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.