

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
12345## Context67This instruction file applies to all Spring Boot Java source files. The project uses Spring Boot 3.x as its baseline, which requires Java 17+ and the Jakarta EE namespace (`jakarta.*`). New microservices target Java 21 and should leverage virtual threads and modern language features where appropriate. This context layer does not apply to legacy Spring MVC modules — see `java-legacy.instructions.md` for those.89---1011## Coding Standards1213- **Java version baseline:** Java 17 minimum; prefer Java 21 features where the runtime supports them14- **Namespace:** Always `jakarta.*` — never `javax.*` in Spring Boot 3.x code15- **Records over POJOs:** Use Java records for immutable DTOs and value objects; reserve classes for mutable entities16- **Text blocks:** Use `"""..."""` for multi-line SQL, JSON, or HTML strings17- **Pattern matching:** Use `instanceof` pattern matching (`if (obj instanceof MyType t)`) — no explicit cast18- **Sealed types:** Use sealed interfaces/classes to model closed domain hierarchies19- **Switch expressions:** Use `switch` expressions with arrow syntax over `switch` statements20- **Constructor injection only:** All Spring-managed beans use constructor injection; mark injected fields `final`21- **No field `@Autowired`:** Never inject via `@Autowired` on a field — it hides dependencies and breaks testability22- **`@ConfigurationProperties`:** All externalized config must use a typed `@ConfigurationProperties` class — no `@Value` on individual fields for grouped config23- **`application.yml`:** Always YAML, never `.properties` format — structure config hierarchically2425---2627## Google Java Style Guide2829All Java code must conform to the **Google Java Style Guide** (https://google.github.io/styleguide/javaguide.html). Key rules:3031- **Indentation:** 2 spaces (not 4, not tabs) for Google style; continuation lines indented +432- **Column limit:** 100 characters per line33- **Braces:** Egyptian style — opening brace on the same line, always use braces even for single-line `if`/`for`/`while` blocks34- **Blank lines:** One blank line between class members; no blank lines after opening brace or before closing brace35- **Import ordering:** Static imports first, then grouped by package, no wildcard imports36- **Variable declarations:** One declaration per line; `var` is allowed for local variables where the type is obvious37- **Annotations:** One annotation per line for class/method declarations38- **Javadoc:** All `public` and `protected` members must have Javadoc; use `@param`, `@return`, `@throws`39- **Naming:** See the naming rules in the global `copilot-instructions.md`; additionally: acronyms treated as words (`HttpUrl`, not `HTTPUrl`)40- **`@Override`:** Always include `@Override` when a method overrides or implements4142```java43// CORRECT: Google Java Style44public final class OrderService {4546 private static final Logger log = LoggerFactory.getLogger(OrderService.class);4748 private final OrderRepository orderRepository;49 private final OrderMapper orderMapper;5051 public OrderService(OrderRepository orderRepository, OrderMapper orderMapper) {52 this.orderRepository = orderRepository;53 this.orderMapper = orderMapper;54 }5556 /**57 * Retrieves an order by its unique identifier.58 *59 * @param id the order UUID60 * @return the order response DTO61 * @throws OrderNotFoundException if no order exists with the given ID62 */63 public OrderResponse findById(UUID id) {64 return orderRepository65 .findById(id)66 .map(orderMapper::toResponse)67 .orElseThrow(() -> new OrderNotFoundException(id));68 }69}70```7172---7374## Maven Best Practices7576All Maven projects must follow these conventions:7778### POM Structure7980```xml81<project xmlns="http://maven.apache.org/POM/4.0.0"82 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"83 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">84 <modelVersion>4.0.0</modelVersion>8586 <!-- Inherit Spring Boot BOM for dependency version management -->87 <parent>88 <groupId>org.springframework.boot</groupId>89 <artifactId>spring-boot-starter-parent</artifactId>90 <version>3.2.x</version>91 <relativePath/>92 </parent>9394 <groupId>com.example</groupId>95 <artifactId>my-service</artifactId>96 <version>1.0.0-SNAPSHOT</version>97 <packaging>jar</packaging>9899 <properties>100 <!-- Always pin Java version explicitly -->101 <java.version>21</java.version>102 <maven.compiler.source>${java.version}</maven.compiler.source>103 <maven.compiler.target>${java.version}</maven.compiler.target>104 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>105 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>106 <!-- Library versions not managed by Spring BOM go here -->107 <mapstruct.version>1.5.5.Final</mapstruct.version>108 <testcontainers.version>1.19.x</testcontainers.version>109 </properties>110</project>111```112113### Dependency Rules114115- **Use Spring Boot BOM** — never declare `<version>` for Spring Boot-managed dependencies116- **No version in child modules** — all versions declared in parent's `<dependencyManagement>`117- **Scope everything correctly:** `test` scope for test-only libs, `provided` for servlet-api in WAR118- **No `LATEST` or `RELEASE` versions** — always pin exact versions119- **Bill of Materials (BOM) imports** for multi-library stacks (Testcontainers, etc.)120- **Dependency hygiene:** Run `mvn dependency:analyze` to find unused declared and undeclared used dependencies121122### Required Maven Plugins123124```xml125<build>126 <plugins>127 <!-- Enforce minimum Maven and Java versions -->128 <plugin>129 <groupId>org.apache.maven.plugins</groupId>130 <artifactId>maven-enforcer-plugin</artifactId>131 <executions>132 <execution>133 <id>enforce</id>134 <goals><goal>enforce</goal></goals>135 <configuration>136 <rules>137 <requireMavenVersion><version>[3.9,)</version></requireMavenVersion>138 <requireJavaVersion><version>[17,)</version></requireJavaVersion>139 <dependencyConvergence/>140 <banDuplicatePomDependencyVersions/>141 </rules>142 </configuration>143 </execution>144 </executions>145 </plugin>146147 <!-- Code coverage — enforce minimums -->148 <plugin>149 <groupId>org.jacoco</groupId>150 <artifactId>jacoco-maven-plugin</artifactId>151 <executions>152 <execution>153 <id>prepare-agent</id>154 <goals><goal>prepare-agent</goal></goals>155 </execution>156 <execution>157 <id>check</id>158 <goals><goal>check</goal></goals>159 <configuration>160 <rules>161 <rule>162 <element>BUNDLE</element>163 <limits>164 <limit>165 <counter>LINE</counter>166 <value>COVEREDRATIO</value>167 <minimum>0.80</minimum>168 </limit>169 <limit>170 <counter>BRANCH</counter>171 <value>COVEREDRATIO</value>172 <minimum>0.70</minimum>173 </limit>174 </limits>175 </rule>176 </rules>177 </configuration>178 </execution>179 <execution>180 <id>report</id>181 <goals><goal>report</goal></goals>182 </execution>183 </executions>184 </plugin>185186 <!-- SpotBugs static analysis -->187 <plugin>188 <groupId>com.github.spotbugs</groupId>189 <artifactId>spotbugs-maven-plugin</artifactId>190 <version>4.8.x</version>191 <executions>192 <execution>193 <goals><goal>check</goal></goals>194 </execution>195 </executions>196 </plugin>197198 <!-- Checkstyle — enforce Google Java Style -->199 <plugin>200 <groupId>org.apache.maven.plugins</groupId>201 <artifactId>maven-checkstyle-plugin</artifactId>202 <version>3.3.x</version>203 <configuration>204 <configLocation>google_checks.xml</configLocation>205 <failOnViolation>true</failOnViolation>206 <violationSeverity>warning</violationSeverity>207 </configuration>208 <executions>209 <execution>210 <id>checkstyle</id>211 <phase>verify</phase>212 <goals><goal>check</goal></goals>213 </execution>214 </executions>215 </plugin>216217 <!-- OWASP Dependency-Check — flag known CVEs in dependencies -->218 <plugin>219 <groupId>org.owasp</groupId>220 <artifactId>dependency-check-maven</artifactId>221 <version>9.x</version>222 <configuration>223 <failBuildOnCVSS>7</failBuildOnCVSS>224 </configuration>225 </plugin>226 </plugins>227</build>228```229230### Maven Profiles231232```xml233<profiles>234 <!-- Integration tests run separately from unit tests -->235 <profile>236 <id>integration-tests</id>237 <build>238 <plugins>239 <plugin>240 <groupId>org.apache.maven.plugins</groupId>241 <artifactId>maven-failsafe-plugin</artifactId>242 <executions>243 <execution>244 <goals>245 <goal>integration-test</goal>246 <goal>verify</goal>247 </goals>248 </execution>249 </executions>250 </plugin>251 </plugins>252 </build>253 </profile>254</profiles>255```256257---258259## SonarLint / SonarQube Integration260261All Java code is validated by SonarLint locally and SonarQube/SonarCloud in CI.262263### SonarLint Local (VS Code)264265The `sonarsource.sonarlint-vscode` extension is included in `.vscode/extensions.json`. SonarLint runs in real time. Rules to always resolve before committing:266267- **Blocker / Critical rules:** Must be resolved — never suppress without written justification268- **Major rules:** Resolve or create a ticket before PR269- **`// NOSONAR`:** Only with a trailing comment explaining the rationale; never used to hide real defects270271### SonarQube Maven Integration272273```xml274<!-- Add to parent pom.xml properties -->275<sonar.java.source>21</sonar.java.source>276<sonar.coverage.jacoco.xmlReportPaths>277 ${project.build.directory}/site/jacoco/jacoco.xml278</sonar.coverage.jacoco.xmlReportPaths>279<sonar.exclusions>280 **/generated/**,281 **/*MapperImpl.java,282 **/config/**283</sonar.exclusions>284```285286Run local analysis:287```bash288mvn sonar:sonar \289 -Dsonar.host.url=http://localhost:9000 \290 -Dsonar.token=${SONAR_TOKEN}291```292293### SonarQube Quality Gate Thresholds (enforce in CI)294295| Metric | Minimum |296|--------|---------|297| New code coverage | 80% |298| New code duplications | < 3% |299| New bugs | 0 |300| New vulnerabilities | 0 |301| New code smells (blocker/critical) | 0 |302| Security hotspots reviewed | 100% |303304---305306## Preferred Patterns307308### REST Controller309310```java311@RestController312@RequestMapping("/api/v1/orders")313@Tag(name = "Orders", description = "Order management endpoints")314@RequiredArgsConstructor // if Lombok is already on classpath; else write constructor manually315public class OrderController {316317 private final OrderService orderService;318319 @GetMapping("/{id}")320 @Operation(summary = "Retrieve an order by ID")321 public ResponseEntity<OrderResponse> getOrder(@PathVariable UUID id) {322 return ResponseEntity.ok(orderService.findById(id));323 }324325 @PostMapping326 @ResponseStatus(HttpStatus.CREATED)327 public OrderResponse createOrder(@Valid @RequestBody CreateOrderRequest request) {328 return orderService.create(request);329 }330}331```332333### Exception Handling (RFC 7807 ProblemDetail)334335```java336@RestControllerAdvice337public class GlobalExceptionHandler {338339 @ExceptionHandler(OrderNotFoundException.class)340 public ProblemDetail handleOrderNotFound(OrderNotFoundException ex) {341 ProblemDetail problem = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage());342 problem.setTitle("Order Not Found");343 return problem;344 }345346 @ExceptionHandler(MethodArgumentNotValidException.class)347 public ProblemDetail handleValidation(MethodArgumentNotValidException ex) {348 ProblemDetail problem = ProblemDetail.forStatus(HttpStatus.UNPROCESSABLE_ENTITY);349 problem.setTitle("Validation Failed");350 problem.setProperty("violations", ex.getBindingResult().getFieldErrors()351 .stream().map(e -> e.getField() + ": " + e.getDefaultMessage()).toList());352 return problem;353 }354}355```356357### Spring Data JPA Repository358359```java360public interface OrderRepository extends JpaRepository<Order, UUID> {361362 List<Order> findByCustomerIdAndStatus(UUID customerId, OrderStatus status);363364 @Query("SELECT o FROM Order o JOIN FETCH o.lineItems WHERE o.id = :id")365 Optional<Order> findByIdWithLineItems(@Param("id") UUID id);366367 Page<Order> findByCreatedAtAfter(Instant cutoff, Pageable pageable);368}369```370371### Spring Security 6.x Configuration372373```java374@Configuration375@EnableMethodSecurity376public class SecurityConfig {377378 @Bean379 public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {380 return http381 .csrf(AbstractHttpConfigurer::disable)382 .authorizeHttpRequests(auth -> auth383 .requestMatchers("/actuator/health", "/actuator/info").permitAll()384 .requestMatchers("/api/**").authenticated()385 .anyRequest().denyAll()386 )387 .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))388 .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))389 .build();390 }391}392```393394### Typed Configuration Properties395396```java397@ConfigurationProperties(prefix = "app.payment")398public record PaymentProperties(399 String gatewayUrl,400 Duration timeout,401 int maxRetries402) {}403```404405```yaml406# application.yml407app:408 payment:409 gateway-url: https://payment.example.com410 timeout: 30s411 max-retries: 3412```413414### Java 21 Virtual Threads415416```java417@Bean418public TomcatProtocolHandlerCustomizer<?> virtualThreadsCustomizer() {419 return handler -> handler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());420}421```422423---424425## Anti-Patterns — Do NOT Generate426427```java428// WRONG: field injection429@Autowired430private OrderService orderService;431432// WRONG: javax namespace in Spring Boot 3433import javax.persistence.Entity;434435// WRONG: WebSecurityConfigurerAdapter (removed in Spring Security 6)436public class SecurityConfig extends WebSecurityConfigurerAdapter { ... }437438// WRONG: @Value on individual fields for grouped config439@Value("${app.payment.gateway-url}")440private String gatewayUrl;441442// WRONG: returning null from service methods — use Optional or throw443public Order findOrder(UUID id) {444 return repository.findById(id).orElse(null);445}446447// WRONG: catching and swallowing exceptions448try {449 processPayment(order);450} catch (Exception e) {451 // silent swallow452}453454// WRONG: application.properties file455# app.payment.gateway-url=https://...456```457458---459460## Dependencies & Versions461462| Library | Version | Import Style |463|---------|---------|-------------|464| Spring Boot | 3.2.x+ | `org.springframework.boot` |465| Spring Security | 6.x | `org.springframework.security` |466| Spring Data JPA | 3.x | `org.springframework.data.jpa` |467| springdoc-openapi | 2.x | `org.springdoc` |468| MapStruct | 1.5.x | `org.mapstruct` |469| Jakarta EE | 10 | `jakarta.*` |470| Java | 17 / 21 | — |471472---473474## Test Conventions475476- Use `@WebMvcTest(MyController.class)` for controller layer tests — not full `@SpringBootTest`477- Use `@DataJpaTest` for repository tests — auto-configures H2 or Testcontainers478- Use `@MockBean` to inject mocked dependencies in slice tests479- Use `MockMvc` with `ObjectMapper` for controller request/response verification480- Name integration test classes with suffix `IT` — they run in a separate Maven phase481- Use `@Testcontainers` + `@Container` for tests requiring a real database or message broker482
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| doubts-suplab/eeik-bootstrap.clinerules/golden-rules.md · 1 | Cline rules | gitsecuritydo-not | 61/100 | today | |
| doubts-suplab/eeik-bootstrap.clinerules/project.md · 1 | Cline rules | teststylegit | 63/100 | today | |
| doubts-suplab/eeik-bootstrap.cursor/rules/architecture.mdc · 1 | Cursor rules | do-not | 52/100 | today | |
| doubts-suplab/eeik-bootstrap.cursor/rules/capabilities.mdc · 1 | Cursor rules | teststylegit | 58/100 | today | |
| doubts-suplab/eeik-bootstrap.cursor/rules/golden-rules.mdc · 1 | Cursor rules | gitsecuritydo-not | 61/100 | today | |
| doubts-suplab/eeik-bootstrap.cursor/rules/python.mdc · 1 | Cursor rules | lint-formatstyletypesapi+1 | 77/100 | today | |
| doubts-suplab/eeik-bootstrap.cursor/rules/security.mdc · 1 | Cursor rules | security | 39/100 | today | |
| doubts-suplab/eeik-bootstrap.github/copilot-instructions.md · 1 | Copilot instructions | lint-formatstyletesting-strategygit+2 | 54/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/a2a-protocol.instructions.md · 1 | Copilot instructions | styleagent-behaviour | 48/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/ai-governance.instructions.md · 1 | Copilot instructions | stylearchdo-notagent-behaviour | 61/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/angular.instructions.md · 1 | Copilot instructions | teststyletypestesting-strategy+4 | 69/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/architecture-governance.instructions.md · 1 | Copilot instructions | testlint-formatstylegit+4 | 65/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/autogen.instructions.md · 1 | Copilot instructions | typessecurityagent-behaviour | 50/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/aws-architecture.instructions.md · 1 | Copilot instructions | styletypessecurityperformance | 58/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/aws-data-ml-ai.instructions.md · 1 | Copilot instructions | deployment | 54/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/cdk-terraform.instructions.md · 1 | Copilot instructions | teststylearchtypes+2 | 96/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/cicd.instructions.md · 1 | Copilot instructions | stylesecuritydeploymentdo-not+1 | 65/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/containerisation.instructions.md · 1 | Copilot instructions | buildstylesecuritydo-not | 77/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/crewai.instructions.md · 1 | Copilot instructions | styleagent-behaviour | 48/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/data-engineering.instructions.md · 1 | Copilot instructions | teststyletypesgit+5 | 69/100 | today |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| HerringtonDarkholme/megarepo.github/copilot-instructions.md · 17 | Copilot instructions | setupbuildtestlint-format+7 | 100/100 | 14 days ago | |
| louislam/uptime-kuma.github/copilot-instructions.md · 90k | Copilot instructions | setupbuildtestlint-format+9 | 100/100 | 14 days ago | |
| chihebnabil/lovable-boilerplate.github/instructions/global.instructions.md · 65 | Copilot instructions | buildlint-formatstylearch+4 | 100/100 | 14 days ago | |
| pytorch/pytorch.github/copilot-instructions.md · 102k | Copilot instructions | setupbuildteststyle+5 | 100/100 | 14 days ago | |
| JCodesMore/ai-website-cloner-template.github/copilot-instructions.md · 32k | Copilot instructions | buildlint-formatstylearch+3 | 97/100 | 7 days ago | |
| bagisto/bagisto.github/copilot-instructions.md · 28k | Copilot instructions | setupbuildteststyle+5 | 97/100 | 14 days ago | |
| hiyouga/LlamaFactory.github/copilot-instructions.md · 74k | Copilot instructions | setupbuildtestlint-format+5 | 97/100 | 13 days ago | |
| darkmatter/nixmac.github/copilot-instructions.md · 25 | Copilot instructions | setupbuildtestlint-format+8 | 96/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/doubts-suplab-eeik-bootstrap-github-instructions-spring-boot-instructions)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.