plugins/github-copilot-modernization/skills/guidelines/struts-to-spring/SKILL.md
# Struts 2 to Spring Boot 3.x Migration Guideline ## Metadata - **Source Technology**: Apache Struts 2 (struts2-core) - **Target Technology**: Spring Boot 3.x with Spring MVC - **Trigger Keywords**: struts, struts2, ActionSupport, struts.xml, xwork2, opensymphony, struts-tags - **Version**: 1.0.0 - **Last Updated**: 2025-01-22 ## Overview This guideline provides comprehensive skills for migrating Apache Struts 2 applications to Spring Boot 3.x. Each skill addresses a specific migration conce
npx skillsauth add microsoft/github-copilot-modernization plugins/github-copilot-modernization/skills/guidelines/struts-to-springInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This guideline provides comprehensive skills for migrating Apache Struts 2 applications to Spring Boot 3.x. Each skill addresses a specific migration concern with concrete transformation rules, examples, and validation criteria.
| File | Skills | Description | |------|--------|-------------| | SKILL-config.md | migrate-maven-dependencies, create-spring-boot-application, create-application-properties | Project setup and configuration | | SKILL-action.md | convert-action-to-controller, convert-action-properties | Action to Controller conversion | | SKILL-view.md | convert-jsp-tags, convert-ognl-to-el, convert-result-types | View layer migration | | SKILL-interceptor.md | convert-interceptor, convert-validation | Interceptors and validation | | SKILL-xml.md | migrate-struts-xml, migrate-web-xml | XML configuration migration | | SKILL-test.md | convert-test-classes, create-exception-handler | Testing and exception handling |
Execute skills in this order:
migrate-maven-dependencies - Update pom.xml (SKILL-config.md)create-spring-boot-application - Create main class (SKILL-config.md)create-application-properties - Create configuration (SKILL-config.md)migrate-struts-xml - Plan controller structure (SKILL-xml.md)migrate-web-xml - Remove Struts filter (SKILL-xml.md)convert-action-to-controller - Convert each Action class (SKILL-action.md)convert-action-properties - Handle Action properties (SKILL-action.md)convert-validation - Migrate validation logic (SKILL-interceptor.md)convert-interceptor - Convert interceptors (SKILL-interceptor.md)convert-result-types - Handle result mappings (SKILL-view.md)convert-jsp-tags - Update JSP files (SKILL-view.md)convert-ognl-to-el - Fix expressions (SKILL-view.md)convert-test-classes - Update tests (SKILL-test.md)create-exception-handler - Global exception handling (SKILL-test.md)HelloAction.java:
package com.example.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport {
private String name;
private String message;
public String execute() {
if (name == null || name.isEmpty()) {
return INPUT;
}
message = "Hello, " + name + "!";
return SUCCESS;
}
public void validate() {
if (name != null && name.length() > 50) {
addFieldError("name", "Name too long");
}
}
// getters and setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getMessage() { return message; }
}
struts.xml:
<action name="hello" class="com.example.action.HelloAction">
<result name="success">/WEB-INF/jsp/hello.jsp</result>
<result name="input">/WEB-INF/jsp/hello-form.jsp</result>
</action>
hello.jsp:
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<body>
<s:property value="message"/>
</body>
</html>
HelloForm.java:
package com.example.form;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
public class HelloForm {
@NotBlank(message = "Name is required")
@Size(max = 50, message = "Name too long")
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
HelloController.java:
package com.example.controller;
import com.example.form.HelloForm;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class HelloController {
@GetMapping("/hello")
public String showForm(Model model) {
model.addAttribute("helloForm", new HelloForm());
return "hello-form";
}
@PostMapping("/hello")
public String execute(@Valid @ModelAttribute HelloForm form,
BindingResult result,
Model model) {
if (result.hasErrors()) {
return "hello-form";
}
String message = "Hello, " + form.getName() + "!";
model.addAttribute("message", message);
return "hello";
}
}
hello.jsp:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<body>
${message}
</body>
</html>
Application.java:
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
application.properties:
server.port=8080
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
development
Evaluates whether a user's modernization/rewrite request provides enough scenario context to proceed (e.g., target component library, screenshots, design system for frontend; API contract policy, data migration strategy for backend). Produces a deterministic clarity score, asks the user for missing required fields via a structured form, and writes a canonical `clarification.md` artifact consumed by all downstream agents. Triggers: "clarification gate", "scenario clarification", "elicit missing context", "evaluate prompt completeness", "ask user for screenshots / target library / design system". NOT for: feature specification (use feature-inventory), planning (use creating-implementation-plan), implementation (use implementing-code), or resolving spec-time `[NEEDS CLARIFICATION]` markers (those remain owned by feature-inventory).
tools
Lifecycle hooks for the modernize-rearchitecture coordinator. Defines hook points, registered actions, and execution rules.
development
Provides role charters (mission, ownership, core principles, quality bar) for a multi-agent coding team. Each charter defines the role's mission, ownership scope, core principle (boundary constraints), and quality bar. Most roles also include communication rules. Consumed by the coordinator during task decomposition to assign work to the correct role. Triggers: "look up role charter", "what does the architect own", "check role boundaries", "find team roles", "which role handles X", "list agent charters", "role responsibilities". NOT for: task decomposition (use breaking-down-tasks), implementation (use implementing-code), architecture analysis (use analyzing-architecture).
tools
Zero-dependency shell recon for any code repository — detect languages, count LOC, and report project scale. Pure POSIX find/wc or PowerShell, no Python or third-party tools required. Triggers: "how big is this project", "what languages", "project sizing", "repo recon", "LOC count", "scope check".