Java Evolved — Code Upgrade Skill
Modernize Java code by identifying legacy patterns and suggesting modern replacements with before/after examples sourced from 113 patterns across 11 categories (Java 7 through Java 25).
Procedures
Step 1: Determine Upgrade Scope
- Identify the target JDK version for the project. Check
pom.xml,build.gradle, or.java-versionfor the configured source/target level. If unspecified, ask the user. - Identify which categories are relevant to the task:
language— var, records, sealed classes, pattern matching, switch expressions, text blockscollections— immutable factories, sequenced collections, unmodifiable collectorsstrings— isBlank, strip, repeat, lines, formatted, text blocksstreams— toList, mapMulti, gatherers, takeWhile/dropWhile, optional improvementsconcurrency— virtual threads, structured concurrency, scoped values, stable valuesio— HTTP client, Files API, Path.of, transferTo, memory-mapped fileserrors— helpful NPE, multi-catch, optional chaining, null-in-switchdatetime— java.time API, Duration/Period, HexFormat, Math.clampsecurity— PEM encoding, KDF, strong random, TLS defaultstooling— JShell, single-file execution, JFR, AOT preloadingenterprise— EJB to CDI, Servlet to JAX-RS, JDBC to JPA/jOOQ, SOAP to REST, Spring modernization
- If performing a full codebase scan, proceed to Step 2. If upgrading specific code, skip to Step 3.
Step 2: Scan for Legacy Patterns
- Read
references/detection-patterns.mdto load the detection signature database. - For each relevant category, search the codebase for the detection signatures listed:
- Use grep/search for the specific code patterns documented (e.g.,
Collections.unmodifiableList,new Thread(,.trim().isEmpty()) - Track each match with file path, line number, and matched pattern slug.
- Use grep/search for the specific code patterns documented (e.g.,
- Execute
python3 scripts/find-pattern.py --data-dir references/ --category {cat} --max-jdk {target} --format fullto retrieve the complete before/after transformation for each detected pattern. - Group findings by priority:
- Quick wins: beginner difficulty, drop-in replacements (e.g.,
var,List.of(),String.isBlank()) - Moderate: intermediate difficulty, may require testing (e.g., records, sealed classes, virtual threads)
- Significant: advanced difficulty, architectural changes (e.g., structured concurrency, enterprise migrations)
- Quick wins: beginner difficulty, drop-in replacements (e.g.,
- Format results using
assets/upgrade-report-template.md.
Step 3: Upgrade Specific Code
- Identify which legacy pattern the code uses. If unsure, read
references/detection-patterns.mdand match against the code. - Look up the specific pattern by executing:
python3 scripts/find-pattern.py --data-dir references/ --keyword "{pattern_name}" --format full - Read the relevant category reference file from
references/{category}.mdfor the complete transformation including:- Before/after code examples
- Explanation of why the modern approach is better
- JDK version requirements
- Related patterns to consider alongside
- Apply the transformation following the modern code example. Adapt to the specific codebase context — do not blindly copy-paste.
- Check for related patterns that often co-occur. The reference files list
relatedpatterns for each entry.
Step 4: Enterprise Migration Path
If the codebase involves Java EE or early Jakarta EE, read references/enterprise.md for the complete migration mappings:
- EJB to CDI beans
- Servlet to JAX-RS endpoints
- JSF managed beans to CDI named beans
- JNDI lookups to CDI injection
- JPA EntityManager to Jakarta Data repositories
- SOAP web services to Jakarta REST
- Message-driven beans to reactive messaging
- Manual transactions to declarative @Transactional
- Spring XML configuration to annotation-driven
- Spring null safety to JSpecify
Step 5: Validate Upgrades
- Verify the target JDK version supports all applied patterns. Each pattern specifies its minimum JDK version.
- Ensure no pattern requires a JDK version higher than the project target.
- Run the project's existing test suite to confirm no regressions.
- For patterns marked as preview features, verify the project enables preview:
--enable-preview.
Quick Reference by JDK Version
| JDK | Key Patterns |
|---|---|
| 7 | multi-catch, diamond operator |
| 8 | default/static interface methods, streams, CompletableFuture, java.time |
| 9 | List/Set/Map.of(), Optional.or/ifPresentOrElse, private interface methods, Stream.ofNullable/takeWhile/dropWhile, process API |
| 10 | var, unmodifiable copy, Optional.orElseThrow |
| 11 | String.isBlank/strip/repeat/lines, HTTP client, Path.of, single-file execution, Predicate.not |
| 12 | String.indent/transform, Files.mismatch, Collectors.teeing |
| 14 | switch expressions, helpful NPE |
| 15 | text blocks, String.formatted |
| 16 | records, Stream.toList, mapMulti, unmodifiable collectors, record-based errors, static members in inner classes |
| 17 | sealed classes, RandomGenerator, HexFormat |
| 18 | built-in HTTP server |
| 19 | executor try-with-resources, Thread.sleep(Duration) |
| 21 | virtual threads, pattern matching (instanceof + switch), sequenced collections, unnamed variables, guarded patterns, null-in-switch, Math.clamp |
| 22 | unnamed variables, multi-file source, FFM API (call C from Java), file memory mapping |
| 23 | markdown Javadoc |
| 24 | stream gatherers |
| 25 | structured concurrency, scoped values, stable values, flexible constructors, compact source files, module imports, primitive patterns, AOT preloading, PEM encoding, KDF, IO class |
Error Handling
- If
scripts/find-pattern.pyfails with a file-not-found error, verify the--data-dirpoints to thereferences/directory containing the category markdown files. - If a pattern requires a JDK version higher than the project target, flag it as "future upgrade" rather than applying it.
- If the YAML data files are missing, the reference markdown files in
references/contain all pattern data and can be used directly without the script. - If a detection signature matches but the code context differs from the pattern (e.g., intentional use of old API), skip the suggestion and note why.