/SKILL.md
Transforms legacy Java code to modern idioms. Use when migrating Java versions, converting verbose POJOs/DTOs to records, platform threads to virtual threads, for-loops to streams, anonymous classes to lambdas, or when a codebase targets Java 11-25 but uses older patterns. Version-aware (Java 8-25), framework-smart (Spring Boot, Quarkus, Micronaut), detects version from pom.xml or build.gradle automatically.
npx skillsauth add ajaywadhara/modern-java modern-javaInstall 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.
You are an expert Java developer that modernizes legacy Java code to use modern idioms. You don't just provide suggestions—you actively find, transform, and apply modern patterns.
Find and parse build files in this priority order:
Version Detection:
gradle/libs.versions.toml (Gradle Version Catalog)pom.xml (Maven)build.gradle / build.gradle.kts (Gradle)Version patterns:
<!-- Maven pom.xml -->
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<release>21</release>
# Gradle libs.versions.toml
[versions]
java = "21"
# Gradle build.gradle
sourceCompatibility = '21'
java { toolchain { languageVersion = JavaLanguageVersion.of(21) } }
Framework Detection:
| File | Frameworks Detected | |------|-------------------| | pom.xml | Quarkus, Spring Boot, Micronaut, Hibernate, JUnit 5 | | build.gradle | Quarkus, Spring Boot, Micronaut, Hibernate, JUnit 5 | | application.properties | Quarkus, Spring Boot, Micronaut | | application.yml | Quarkus, Spring Boot, Micronaut |
If no version found, assume Java 21 LTS.
Based on detected version, load relevant reference files:
| Detected Version | Load These Files |
|-----------------|------------------|
| 8-11 | 01-java8-11.md |
| 12-17 | 01-java8-11.md, 02-java12-17.md |
| 18-21 | 01-java8-11.md, 02-java12-17.md, 03-java18-21.md |
| 22-25 | ALL files |
Example: If version = 17, load files 01 and 02. Skip 03 and 04.
Scan .java files for these patterns:
| Pattern | Modern Alternative | Min Version | |---------|-------------------|-------------| | Anonymous inner classes | Lambda expressions | 8 | | For loops with filtering | Stream API | 8 | | Null check chains | Optional | 8 | | Mutable DTOs/POJOs | Records | 16 | | Traditional switch | Switch expressions | 14 | | instanceof + cast | Pattern matching | 16 | | Platform threads | Virtual threads | 21 | | ThreadLocal | ScopedValue | 25 | | HttpURLConnection | HttpClient | 11 | | Verbose collections | List.of(), Map.of() | 9 |
For each pattern found:
Write the report to MODERNIZATION-REPORT.md in the project root (same directory as pom.xml or build.gradle). Always write the file — do not only print to the conversation.
## Modernization Report
**Project:** my-app
**Java Version:** Java 21
**Spring Boot:** 3.4.1
**Files Scanned:** 47
**Patterns Found:** 23
**Lines Saved:** ~156 (12%)
**Report saved to:** MODERNIZATION-REPORT.md
### Transformations Applied
| File | Pattern | Lines Saved |
|------|---------|-------------|
| OrderDTO.java | DTO → Record | -45 |
| UserService.java | for loop → Stream | -12 |
| ApiClient.java | HttpURLConnection → HttpClient | -28 |
After writing the file, tell the user:
"Report saved to
MODERNIZATION-REPORT.mdin your project root."
Spring Boot:
@ConstructorBinding for @ConfigurationPropertiesRestClient (Java 21+) instead of RestTemplateQuarkus:
@Record for reactive transformationsMicronaut:
// BEFORE: 50+ lines
public class Person {
private final String name;
private int age;
public Person(String name, int age) { ... }
public String getName() { return name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
// equals, hashCode, toString...
}
// AFTER: 1 line
public record Person(String name, int age) {}
// BEFORE: Limited concurrency
ExecutorService executor = Executors.newFixedThreadPool(100);
// AFTER: Millions of tasks
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(() -> handle(request));
}
// BEFORE: if-else chain
if (obj instanceof Integer i) { ... }
else if (obj instanceof String s) { ... }
// AFTER: switch expression
return switch (obj) {
case Integer i -> "int: " + i;
case String s -> "string: " + s;
default -> "unknown";
};
Load these files based on detected Java version:
When user asks to modernize code:
.java filesExample invocations:
development
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.
development
Maintainer workflow for OpenClaw releases, prereleases, changelog release notes, and publish validation. Use when Codex needs to prepare or verify stable or beta release steps, align version naming, assemble release notes, check release auth requirements, or validate publish-time commands and artifacts.
development
Run, watch, debug, and extend OpenClaw QA testing with qa-lab and qa-channel. Use when Codex needs to execute the repo-backed QA suite, inspect live QA artifacts, debug failing scenarios, add new QA scenarios, or explain the OpenClaw QA workflow. Prefer the live OpenAI lane with regular openai/gpt-5.4 in fast mode; do not use gpt-5.4-pro or gpt-5.4-mini unless the user explicitly overrides that policy.
development
End-to-end Parallels smoke, upgrade, and rerun workflow for OpenClaw across macOS, Windows, and Linux guests. Use when Codex needs to run, rerun, debug, or interpret VM-based install, onboarding, gateway smoke tests, latest-release-to-main upgrade checks, fresh snapshot retests, or optional Discord roundtrip verification under Parallels.