agentleFS
base58edbase58ed/claude_code_files/skills/java-prod-skill/SKILL.md

java-prod-skill

Skill1 starsChanged 3 months agoMITView on GitHub

Java production readiness patterns. Load for "prod review", "production review", "review for production", "make production ready", or "productionize" on Java code.

The file

We split this skill into the rules it gives an agent

5 rules. About 0 are common, 3 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Flags: No correlation ID, logging PII/secrets, empty error logs, wrong log levels, missing box() on primitives, string concat in log calls

    line 84
  2. Distinctive:

    Prefer immutability and thread confinement over synchronization.

    line 99
  3. Distinctive:

    Flags: No size limits on input, SQL concatenation, unsanitized paths, no rate limiting

    line 122
  4. Very specific:

    Use framework health endpoints (SmallRye @Liveness/@Readiness, Spring Actuator - see java-skill references), never hand-rolled /health.

    line 142
  5. Distinctive:

    Flags: No health endpoint, dependency checks wired into liveness, no latency/error metrics, no alerting

    line 144

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Production Readiness

Patterns for reviewing production-grade Java code. Complements java-skill.

Resource Management

Set timeouts on ALL external calls. Use try-with-resources. Implement graceful shutdown.

var client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(5)).build();
var request = HttpRequest.newBuilder(uri).timeout(Duration.ofSeconds(30)).build();

// Graceful shutdown pattern
@Override public void close() {
  executor.shutdown();
  if (!executor.awaitTermination(30, TimeUnit.SECONDS)) { executor.shutdownNow(); }
}

Flags: Missing timeouts, resources not in try-with-resources, no shutdown hook

Retry & Resilience

Retries need exponential backoff and max attempts. Circuit breakers prevent cascade failures.

Failsafe (dev.failsafe:failsafe) is the house library: RetryPolicy + CircuitBreaker + Timeout composed via Failsafe.with(...). The loop below is the zero-dependency shape to recognize in review.

Result<Response> callWithRetry(Request req) {
  for (int attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
    switch (call(req)) {
      case Ok(var r) -> { return Result.ok(r); }
      case Err(var f) -> {
        if (attempt == MAX_ATTEMPTS || !isRetryable(f)) { return new Err<>(f); }
      }
    }
    sleep(BASE_DELAY.multipliedBy(1L << (attempt - 1)));  // exponential backoff
  }
  return Result.err("EXHAUSTED", "max retries exceeded");
}

Circuit breaker: track failures, open circuit after threshold, allow probe after timeout.

Flags: Retry without backoff (thundering herd), backoff without jitter (still synchronizes retry waves), hand-rolled retry where Failsafe is available, no max attempts, no circuit breaker on external deps

Logging & Observability

Log4j2 garbage-free mode with correlation IDs. Propagate ThreadContext across virtual threads. Garbage-free MDC is off by default: it requires log4j2.garbagefreeThreadContextMap=true (full prod config: java-skill references/log4j2.md).

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
import static org.apache.logging.log4j.util.Unbox.box;

private static final Logger log = LogManager.getLogger();

ThreadContext.put("correlationId", correlationId);
try {
  log.info("order started: orderId={}, items={}", orderId, box(items.size()));
  // ...
  log.info("order complete: orderId={}, status={}, durationMs={}", orderId, status, box(elapsed));
} finally {
  ThreadContext.clearAll();
}

// Virtual thread ThreadContext propagation
var contextMap = ThreadContext.getImmutableContext();
executor.submit(() -> {
  ThreadContext.putAll(contextMap);
  try { process(); }
  finally { ThreadContext.clearAll(); }
});

Logging rules: box() all primitives, () -> supplier for expensive args, {} placeholders only (never string concat).

Flags: No correlation ID, logging PII/secrets, empty error logs, wrong log levels, missing box() on primitives, string concat in log calls

Configuration

Externalize environment-specific values. Never hardcode secrets. Use feature flags for risky changes.

@ConfigProperty(name = "service.timeout.seconds", defaultValue = "30") int timeoutSeconds;
@ConfigProperty(name = "feature.new-flow.enabled", defaultValue = "false") boolean newFlowEnabled;

Flags: Hardcoded secrets/API keys, magic numbers, no feature flags for risky changes

Concurrency Safety

Prefer immutability and thread confinement over synchronization.

  • Thread-confined: each virtual thread gets own instance
  • Shared state: use ConcurrentHashMap, atomic types
  • Bounded executors: LinkedBlockingQueue(capacity) + CallerRunsPolicy for backpressure

Flags: Shared mutable state without sync, unbounded queues/pools, busy-wait, blocking on platform threads

Input Validation & Security

Validate at boundaries. Size limits prevent DoS.

Result<Order> createOrder(OrderRequest req) {
  if (req.items() == null || req.items().isEmpty()) { return Result.err("VALIDATION", "items required"); }
  if (req.items().size() > MAX_ORDER_ITEMS) { return Result.err("VALIDATION", "max items exceeded"); }
  // ...
}
  • Parameterized queries only - NEVER concatenate SQL
  • Sanitize file paths: Path.of(filename).getFileName() + verify within base dir

Flags: No size limits on input, SQL concatenation, unsanitized paths, no rate limiting

Database

Scope transactions tightly. Prevent N+1 queries.

// BAD: N+1 queries
for (var order : orders) { var items = itemRepo.findByOrderId(order.id()); }

// GOOD: batch fetch
var itemsByOrder = itemRepo.findByOrderIds(orderIds).stream().collect(groupingBy(Item::orderId));

Flags: Long transactions, N+1 patterns, missing indexes, per-request connections

Health & Metrics

Expose health checks. Track: latency (p50/p95/p99), error rate, throughput, queue depth, pool utilization.

Use framework health endpoints (SmallRye @Liveness/@Readiness, Spring Actuator - see java-skill references), never hand-rolled /health. Dependency checks belong in readiness, never liveness: DB-down should shed traffic, not trigger restarts.

Flags: No health endpoint, dependency checks wired into liveness, no latency/error metrics, no alerting

Review Output Format

## Production Readiness: [READY | NEEDS WORK | BLOCKED]

### Blockers
- [item]: reason

### Warnings
- [item]: reason

### Verified
- Resource management (incl. timeouts): OK
- Retry & resilience: OK
- Logging & observability: OK
- Configuration: OK
- Concurrency safety: OK
- Input validation & security: OK
- Database: OK
- Health & metrics: OK

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.