DEV Community

Santosh Ravi Teja Goteti
Santosh Ravi Teja Goteti

Posted on

I built a Claude Code skill that scores your legacy Java code 1–100 and modernizes it to Java 21

The problem with Java 8 → Java 21 migrations

If you're working on a Java 8 codebase — or trying to break into banking and legacy system roles — this article is for you. Every Java 8 codebase has the same problems. You know they exist, but finding and fixing them across 50,000 lines is slow:

  • double for monetary values → silent FX precision loss in production
  • Unguarded order.getCounterparty().getAccount( ).getBalance() → NPE in settlement
  • synchronized HashMap → race conditions under concurrent trade load
  • Executors.newFixedThreadPool(200) → bottleneck at peak volume
  • 60-line DTOs with manual equals/hashCode → noise hiding domain logic

What I built

A two-skill Claude Code plugin that acts as a
Senior Java Architect:

Skill 1 — /java-modernization-review
Analyzes your Java file, saves a full report to
analysis.md, and stops.
You review it before any code is touched.

Skill 2 — /java-modernization-implement
Reads analysis.md, applies every change,
writes *Modern.java alongside
the original. Never overwrites your file.

The scoring system

Every review produces a Before/After score
across 9 dimensions (100 points total):

## Scoring breakdown (100 points total)

🔴 NPE prevention — 15 pts
🔴 Monetary precision (BigDecimal) — 15 pts
🔴 Thread safety — 15 pts
🟡 Streams & collections — 10 pts
🟡 Exception handling — 10 pts
🟡 Modern data carriers (Records) — 10 pts
🟡 Concurrency model (virtual threads) — 10 pts
🟡 Modern Java features — 10 pts
🟢 Financial domain rules — 5 pts

Real example: TradeProcessor.java

Legacy code the skill flagged as critical:

// C1 — NPE: any of these can be null
  return order.getCounterparty().getAccount().getB
  alance();
Enter fullscreen mode Exit fullscreen mode
 // C2 — Precision loss on every FX trade
 double total = 0.0;
  total += t.getAmount() * t.getFxRate();
Enter fullscreen mode Exit fullscreen mode
  // C2 — Precision loss on every FX trade
 double total = 0.0;
  total += t.getAmount() * t.getFxRate();
Enter fullscreen mode Exit fullscreen mode
 // C3 — Race condition on position updates
  private HashMap<String, Double> positionMap = new HashMap<>();
  public synchronized void updatePosition(String cp, double delta) {
      Double current = positionMap.get(cp);
      positionMap.put(cp, current == null ? delta : current + delta);
  }
Enter fullscreen mode Exit fullscreen mode
// C4 — Swallowed settlement failure
  } catch (Exception e) {
      // TODO: handle later
  }
Enter fullscreen mode Exit fullscreen mode

After /java-modernization-implement:

  // C1 fixed — Optional chain, no NPE possible
 public BigDecimal getCounterpartyBalance(Order order) {
      return Optional.ofNullable(order)
          .map(Order::getCounterparty)
          .map(Counterparty::getAccount)
          .map(Account::getBalance)
          .orElseThrow(() -> new IllegalArgumentException("Account balance unavailable"));
  }

Enter fullscreen mode Exit fullscreen mode
  // C2 + C3 fixed — BigDecimal stream + lock-free map
  private final ConcurrentHashMap<String, BigDecimal> positionMap = new
  ConcurrentHashMap<>();
  public void updatePosition(String counterparty, BigDecimal delta) {
      positionMap.merge(counterparty, delta, BigDecimal::add);
  }
Enter fullscreen mode Exit fullscreen mode
// Java 21 — virtual threads
  private final ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
Enter fullscreen mode Exit fullscreen mode

Score: 3/100 → 95/100 (+92 points)

What it covers — every Java release from 9 to 21

  • Priority 1 — Streams, Optional, method references
  • Priority 2 — var, helpful NPE messages, built-in HTTP client (Java 9–11)
  • Priority 3 — Records, sealed classes, pattern matching, text blocks (Java 12–16)
  • Priority 4 — Virtual threads, structured concurrency, lock-free atomics (Java 17–21)
  • Priority 5 — String templates, type inference improvements (Java 18–21)
  • Priority 6 — Date→java.time, StringBuffer→StringBuilder, reactive→virtual threads
  • Priority 7 — Module system (module-info.java)

Two-step workflow — review before any code changes

Step 1 — /java-modernization-review
→ Analyzes file
→ Saves analysis.md
→ Stops and waits for your approval

Step 2 — /java-modernization-implement
→ Reads analysis.md
→ Applies every change
→ Writes *Modern.java (original untouched)
→ Prints final score + delta

Install in Claude Code

  • /plugin marketplace add Santoshrt999/Java-Claude-Skills
  • /plugin install java-claude-skills@java-modernization-review
  • /plugin install java-claude-skills@java-modernization-implement
  • /reload-plugins

Full source code and the TradeProcessor example are in the repo:
👉

GitHub logo Santoshrt999 / Java-Claude-Skills

Claude Code skill: review and modernize legacy Java 8 code to Java 21 with AI. Generates a 1-100 score. Specialized for financial systems.

Java Claude Skills — Java 8 → Java 21 Modernization for Claude Code

AI-powered Java code modernization skill for Claude Code.
Analyzes legacy Java, generates a prioritized upgrade report, scores it 1–100, and applies every change — all inside your editor.

Java Claude Code License Financial Systems


Why this skill?

Migrating Java 8 code to Java 21 is high-value but tedious — every codebase has the same problems:

Problem Impact
double for monetary values Silent precision loss on every FX calculation
Unguarded chained .get() calls NPE crashes in production settlement flows
synchronized HashMap Race conditions on position updates under load
Fixed thread pools Bottleneck at 200–500 concurrent trades
Boilerplate DTOs with 60+ lines Noise that obscures domain logic

This skill acts as a Senior Java Architect in your Claude Code session. It knows every Java feature from 8 through 21, enforces financial-domain safety rules, and produces code you can ship — not just advice.


Skills

  1. Again, if you're working on a Java 8 codebase — or trying to break into banking and legacy system roles — this repo is built for you.

  2. The financial domain examples are intentional: trade processors, FX arithmetic, position maps, settlement logic. That's the code you'll actually face in banking interviews and on the job. Practice modernizing it here before you touch production.

  3. Curious what scores you're seeing on your own codebases. Drop them in the comments.

Top comments (0)