plugins/github-copilot-modernization/skills/guidelines/spring-boot-scaffolding/SKILL.md
Reference guide for creating a new Spring Boot project during rewrite migration.
npx skillsauth add microsoft/github-copilot-modernization spring-boot-scaffoldingInstall 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.
Reference guide for creating a fresh Spring Boot project with modern best practices. Used during implementation phase when the target project needs to be scaffolded.
You MUST consider the user input before proceeding (if not empty).
| Source Stack | Recommended Target | JDK | Key Changes | |--------------|-------------------|-----|-------------| | Struts 2 | Spring Boot 3.x | 17+ | MVC framework | | JSF 2.x | Spring Boot 3.x | 17+ | REST or Thymeleaf | | EJB 3.x | Spring Boot 3.x | 17+ | DI framework | | Java EE 7/8 | Jakarta EE 10 or Spring Boot 3.x | 17+ | Namespace changes | | Legacy Spring | Spring Boot 3.x | 17+ | Boot conventions |
| Target JDK | LTS Until | Features | |------------|-----------|----------| | JDK 17 | 2029+ | Records, Sealed classes, Pattern matching | | JDK 21 | 2031+ | Virtual threads, Sequenced collections |
Recommendation: Use JDK 21 for new projects unless specific compatibility requirements exist.
Create FEATURE_DIR/target-config.yaml:
target_configuration:
project_name: "[NEW_PROJECT_NAME]"
jdk:
version: 21
vendor: "Eclipse Temurin"
framework:
name: "Spring Boot"
version: "3.2.x"
build_tool:
name: "Maven"
version: "3.9.x"
project_structure:
type: "multi-module" # or single-module
modules:
- name: "api"
description: "REST API controllers"
- name: "service"
description: "Business logic services"
- name: "persistence"
description: "Data access layer"
- name: "common"
description: "Shared utilities and DTOs"
dependencies:
- "spring-boot-starter-web"
- "spring-boot-starter-data-jpa"
- "spring-boot-starter-validation"
- "spring-boot-starter-test"
- "lombok"
- "mapstruct"
database:
type: "PostgreSQL"
migration_tool: "Flyway"
curl https://start.spring.io/starter.zip \
-d type=maven-project \
-d language=java \
-d bootVersion=3.2.0 \
-d baseDir=[PROJECT_NAME] \
-d groupId=com.example \
-d artifactId=[PROJECT_NAME] \
-d name=[PROJECT_NAME] \
-d packageName=com.example.[PACKAGE] \
-d javaVersion=21 \
-d dependencies=web,data-jpa,validation,lombok \
-o [PROJECT_NAME].zip
unzip [PROJECT_NAME].zip
[PROJECT_NAME]/
├── pom.xml # Parent POM
├── api/
│ ├── pom.xml
│ └── src/main/java/com/example/api/controller/
├── service/
│ ├── pom.xml
│ └── src/main/java/com/example/service/
├── persistence/
│ ├── pom.xml
│ └── src/main/java/com/example/persistence/
│ ├── entity/
│ └── repository/
├── common/
│ ├── pom.xml
│ └── src/main/java/com/example/common/
│ ├── dto/
│ └── util/
└── application/
├── pom.xml
└── src/main/java/com/example/Application.java
<?xml version="1.0" encoding="UTF-8"?>
<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>3.2.0</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>[PROJECT_NAME]-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<java.version>21</java.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<modules>
<module>common</module>
<module>persistence</module>
<module>service</module>
<module>api</module>
<module>application</module>
</modules>
</project>
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);
}
}
spring:
application:
name: [PROJECT_NAME]
datasource:
url: jdbc:postgresql://localhost:5432/[DB_NAME]
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: validate
open-in-view: false
flyway:
enabled: true
locations: classpath:db/migration
server:
port: 8080
logging:
level:
com.example: DEBUG
org.springframework: INFO
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
<logger name="com.example" level="DEBUG"/>
</configuration>
package com.example.api.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGenericException(Exception ex) {
ErrorResponse error = new ErrorResponse(
HttpStatus.INTERNAL_SERVER_ERROR.value(),
"Internal server error",
ex.getMessage()
);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
cd [PROJECT_NAME]
./mvnw clean compile
./mvnw test
./mvnw spring-boot:run
curl http://localhost:8080/actuator/health
mvn clean compile)mvn spring-boot:run)| Artifact | Path | Purpose |
|----------|------|---------|
| Target Config | FEATURE_DIR/target-config.yaml | Target stack configuration |
| Project Root | [PROJECT_NAME]/ | Scaffolded project |
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".