agentleFS
drafaeldrafael/coding-harness/skills/java-coder/SKILL.md

java-coder

Skill1 starsChanged 6 months agoMITView on GitHub

Mandatory for every task in a Java codebase, including planning, implementation, debugging, refactoring, review, testing, Maven or Gradle build and dependency changes, performance or security analysis, and Java-related documentation. Detect Java projects from pom.xml, Gradle files, gradlew, or .java sources. Load before inspecting or changing the repository even when the user does not explicitly mention Java. Covers Java 21+, Spring Boot, Swing/EDT, code style, testing, security, and desktop UI.

We split this skill into the rules it gives an agent

32 rules. About 0 are common, 20 are distinctive, and 12 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈20

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 12

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Start from the concrete failure and change the narrowest responsible boundary.

    line 29
  2. Distinctive:

    Do not redesign neighboring subsystems unless the user explicitly approves that expanded scope.

    line 30
  3. Distinctive:

    Prefer a local method or class change over a new service, framework, protocol, ownership model, or lifecycle abstraction.

    line 31
  4. Distinctive:

    Before adding more than a few production types or crossing subsystem boundaries, pause and present the simpler alternative and regression …

    line 33
  5. Distinctive:

    Do not add production APIs or hooks solely to simulate implausible failures in tests.

    line 35
  6. Distinctive:

    Do not preserve failed approaches as compatibility scaffolding.

    line 36
  7. Distinctive:

    After two unsuccessful or unverified attempts at the same issue, stop iterating.

    line 37
  8. Distinctive:

    Before completion, audit the whole diff and remove speculative limits, dead helpers, duplicate lifecycle paths, unused dependencies, and …

    line 38
  9. Distinctive:

    Always prefer simple class names over fully qualified names — add an import instead:

    line 46
  10. Very specific:

    Keep the owning type when it adds important meaning.

    line 49
  11. Very specific:

    Prefer empty-collection factory methods over List/Map/Set.of() for empty collections:

    line 56
  12. Very specific:

    Prefer List.of(array) over Arrays.asList(array)

    line 58
  13. Very specific:

    Never use Optional as a method parameter or class field — it is exclusively a return type

    line 59
  14. Distinctive:

    If Apache Commons Lang v3+ is already on the classpath, use it heavily and actively across the codebase.

    line 65
  15. Distinctive:

    If Lombok is already on the classpath, use it heavily and actively across the codebase to eliminate boilerplate.

    line 73
  16. Very specific:

    Prefer String.formatted(...) over + string concatenation

    line 83
  17. Very specific:

    Prefer stream-based functional iteration over for/while loops

    line 84
  18. Very specific:

    Prefer the ternary operator or a switch expression over if statements where it improves clarity

    line 85
  19. Distinctive:

    Prefer method references over equivalent lambdas when the lambda only forwards its argument to a single method or constructor:

    line 86
  20. Distinctive:

    Keep the lambda form when it adds logic (extra arguments, transformation, multiple statements) — readability wins over terseness

    line 91
  21. Very specific:

    Prefer functional interface composition (Function.andThen / compose, Consumer.andThen, Predicate.and / or / negate / Predicate.not) over …

    line 92
  22. Very specific:

    When overriding, include non-sensitive fields normally and replace sensitive values with a fixed mask like "".

    line 114
  23. Distinctive:

    Prefer small, single-purpose methods over large, multi-purpose methods.

    line 120
  24. Distinctive:

    Keep method declarations and invocations on a single line when they fit reasonably

    line 129
  25. Very specific:

    When a method has multiple arguments and the line becomes too long or hard to read, format each argument on its own line with the closing …

    line 130
  26. Distinctive:

    Never impose personal formatting preferences.

    line 176
  27. Distinctive:

    Use the java-coder and test-coverage skills if available

    line 180
  28. Distinctive:

    Always use AssertJ — never raw JUnit assertions

    line 183
  29. Very specific:

    Prefer @InjectMocks over constructing the tested class manually in @BeforeEach

    line 191
  30. Very specific:

    Prefer var for locals initialized by a constructor or builder call

    line 192
  31. Distinctive:

    Never hardcode credentials, secrets, or tokens — use an appropriate external credential source or secure application-owned store

    line 201
  32. Distinctive:

    Keep security concerns consistent across the stack.

    line 204

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 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

Java Coding Standards

Activation Scope

This skill is mandatory for every task in a Java codebase, not only direct Java source edits. Apply it while planning, investigating, debugging, reviewing, testing, changing Maven or Gradle configuration and dependencies, analyzing security or performance, and updating Java-related documentation. Load task-relevant files under references/ before making decisions or changes.

These are non-negotiable standards. Apply them to every piece of Java or Spring Boot code you write or modify.

General

  • Favor readability over cleverness — write for the next person who reads this code
  • Comment only complex or non-obvious logic — never restate what the code already expresses
  • Choose names that reveal intent for variables, methods, and classes
    • Exception: catch-block variables should be a single character by default (e.g., catch (Exception e), catch (Throwable t)),
      • or catch (Exception ignored) for empty catch blocks,
      • or catch (Exception ex), or catch (Throwable cause) to avoid name conflicts
  • Follow established language and project conventions

Scope and Complexity Discipline

These rules are mandatory for implementation, debugging, security, reliability, and review work:

  • Start from the concrete failure and change the narrowest responsible boundary.
  • Do not redesign neighboring subsystems unless the user explicitly approves that expanded scope.
  • Prefer a local method or class change over a new service, framework, protocol, ownership model, or lifecycle abstraction.
  • A new abstraction needs multiple current production consumers or a clear existing contract. A hypothetical future consumer does not count.
  • Before adding more than a few production types or crossing subsystem boundaries, pause and present the simpler alternative and regression risk to the user.
  • A plan is not evidence that every proposed mechanism is necessary. Revalidate each step against what investigation and tests actually demonstrate.
  • Do not add production APIs or hooks solely to simulate implausible failures in tests.
  • Do not preserve failed approaches as compatibility scaffolding. Revert to the last known-good behavior, isolate the failing boundary, and try the smallest different fix.
  • After two unsuccessful or unverified attempts at the same issue, stop iterating. Reassess the premise, trace the full data/control path, and require boundary-appropriate evidence.
  • Before completion, audit the whole diff and remove speculative limits, dead helpers, duplicate lifecycle paths, unused dependencies, and one-consumer abstractions.

For local Java desktop applications, load references/desktop-apps.md before making security, lifecycle, shutdown, native-view, rendering, or resource-ownership changes.


Imports

  • Always prefer simple class names over fully qualified names — add an import instead:
    • ✅ ClassName | ❌ com.package.ClassName (unless the name conflicts with another import)
  • In production code, use static imports only when the unqualified call is conventional and immediately obvious, such as emptyList() or joining()
  • Keep the owning type when it adds important meaning; never statically import methods from Optional, Validate, StringUtils, or Arrays — write Optional.empty(), Validate.notBlank(...), StringUtils.isBlank(...), and Arrays.stream(...)
  • This production-code rule does not override the static-import conventions for established test DSLs such as AssertJ and Mockito

Collections & Optionals

  • Prefer empty-collection factory methods over List/Map/Set.of() for empty collections:
    • ✅ emptyList(), emptyMap(), emptySet()
  • Prefer List.of(array) over Arrays.asList(array)
  • Never use Optional as a method parameter or class field — it is exclusively a return type

Apache Commons Lang 3

If Apache Commons Lang v3+ is already on the classpath, use it heavily and actively across the codebase. Do not add it as a new dependency — only leverage it when already present.

For the full guidance — including the Strings.CS / Strings.CI migration table for deprecated StringUtils methods and the Validate rules for public-API arguments — see references/apache-commons-lang3.md.


Lombok

If Lombok is already on the classpath, use it heavily and actively across the codebase to eliminate boilerplate. Do not add it as a new dependency — only leverage it when already present.

For the full guidance — including the @RequiredArgsConstructor / @Builder / @Slf4j / @ToString.Exclude rules and the @NonNull vs. Validate.notNull policy for public-API arguments — see references/lombok.md.


Code Style

  • Name schema/domain validation limits: reuse an existing named limit or introduce a descriptive local constant without changing accepted values. Do not merge unrelated limits because their values match or replace every numeric literal mechanically.
  • Always wrap statement bodies in braces, even for single-line blocks
  • Prefer String.formatted(...) over + string concatenation
  • Prefer stream-based functional iteration over for/while loops
  • Prefer the ternary operator or a switch expression over if statements where it improves clarity
  • Prefer method references over equivalent lambdas when the lambda only forwards its argument to a single method or constructor:
    • ✅ .map(String::toLowerCase) | ❌ .map(s -> s.toLowerCase())
    • ✅ .forEach(System.out::println) | ❌ .forEach(x -> System.out.println(x))
    • ✅ .map(User::new) | ❌ .map(dto -> new User(dto))
    • ✅ .filter(Objects::nonNull) | ❌ .filter(x -> x != null)
    • Keep the lambda form when it adds logic (extra arguments, transformation, multiple statements) — readability wins over terseness
  • Prefer functional interface composition (Function.andThen / compose, Consumer.andThen, Predicate.and / or / negate / Predicate.not) over lambdas that only forward inputs through existing Function, Consumer, or Predicate values — see references/functional-composition.md for examples and when to keep the lambda.

var Usage

var is allowed only when the inferred type is immediately and unambiguously clear:

✅ Allowed❌ Disallowed
Constructor calls: var foo = new Foo();Complex or chained expressions
Builder calls: var bar = Bar.builder().build();Method return values where the type is not obvious
  • var is freely allowed in tests at the author's discretion

Sensitive Data & record Classes

  • Do not override toString by default in record classes — use the generated implementation unless the record contains sensitive, secret, or PII data
  • Override toString only when a record has fields that must not leak into logs or error messages
    • Fields to mask include (but are not limited to): password, ssn, apiKey, token, clientSecret, secretKey, privateKey, accessKey, refreshToken
    • When overriding, include non-sensitive fields normally and replace sensitive values with a fixed mask like "****"; never partially reveal secrets unless explicitly required by the domain

Method Design

  • Prefer small, single-purpose methods over large, multi-purpose methods. Extract cohesive phases, deeply nested branches, or complex inline lambdas into clearly named private helpers so the calling method reads as an outline of the operation.
  • Private helpers may have a single caller when they clarify a meaningful step or reduce nesting; reuse is not required. Avoid arbitrary line-count limits, pass-through wrappers, and excessive fragmentation that makes control flow harder to follow.
  • Preserve validation order, transaction/lock boundaries, side effects, and exception behavior when extracting helpers. Do not introduce new services or frameworks merely to shorten methods.

Method Formatting

  • In multiline fluent builders, put each chained call on its own line, in production code and tests. Compact single-line builders may stay on one line; do not expand this into an unrelated formatting sweep.
  • Keep method declarations and invocations on a single line when they fit reasonably
  • When a method has multiple arguments and the line becomes too long or hard to read, format each argument on its own line with the closing parenthesis on a separate line — except for lambda blocks, where }) should remain on the same line:
// ✅ Multi-line when needed
someMethod(
    firstArgument,
    secondArgument,
    thirdArgument
);

someMethodWithLambda(e -> {
    // ...
}); // ✅ should remain on the same line

// ✅ Single line when it fits
someMethod(firstArgument, secondArgument);

Tech Stack

ConcernChoice
LanguageJava 21+ — use modern features (records, sealed classes, patterns)
FrameworkSpring Boot — match the project version; follow Spring idioms
BuildMaven (preferred) or Gradle
PersistenceJPA/Hibernate · PostgreSQL · H2 (tests)
TestingJUnit 5 · Mockito

Spring Boot Rules

For Spring Boot–specific rules — dependency injection, layered architecture, API design, error handling, validation, and code style — see references/spring-boot-rules.md.

Desktop Applications

For local, primarily single-user Java desktop applications, use the proportional design, Swing/EDT, WebView, GraalJS, FlatLaf, and HiDPI guidance in references/desktop-apps.md. Project context and demonstrated risk override public-server defaults; this never weakens credential secrecy, OAuth correctness, user-data integrity, or EDT safety.

Formatting

Resolve formatting rules in this order — stop at the first match:

  1. .editorconfig — if present at the project root, it takes precedence for indent style, indent size, line endings, and charset
  2. IDE code style settings — check for exported scheme files:
    • IntelliJ IDEA (preferred): .idea/codeStyles/, *.xml schemes, or Project.xml
    • Eclipse: .settings/org.eclipse.jdt.core.prefs or a .xml formatter profile
  3. Infer from the codebase — when neither of the above exists, read several existing source files and match their conventions exactly (indentation, brace style, import ordering, line length, etc.)

Never impose personal formatting preferences. The goal is consistency with what is already there.

Testing

Use the java-coder and test-coverage skills if available

Assertions

  • Always use AssertJ — never raw JUnit assertions

Naming

  • Test methods: {methodName}_{precondition}_{expectedOutcome}
  • @DisplayName: human-readable sentence describing the scenario; never echo the method name
  • The instance of the class under test: always subject

Structure

  • Prefer @InjectMocks over constructing the tested class manually in @BeforeEach
  • Prefer var for locals initialized by a constructor or builder call
  • Extract expected values into named constants only when they appear in multiple test cases; inline single-use values

Scope

  • For Spring/server applications, focus tests on business logic and services — do not test JPA/Hibernate entities, DTOs, @Configuration beans, or Spring Data repository implementation details
  • For desktop applications, also test application-owned EDT, lifecycle, persistence, theme, rendering, and fallback behavior as described in references/desktop-apps.md; do not duplicate native-library test suites

Security

  • Never hardcode credentials, secrets, or tokens — use an appropriate external credential source or secure application-owned store
  • Validate and sanitize data at real trust boundaries, especially remotely supplied commands, paths, markup, and URLs
  • Apply OWASP best practices to public web services and other exposed network boundaries — injection, broken access control, and insecure design are never acceptable
  • Keep security concerns consistent across the stack; a secure API means nothing if the service layer bypasses it
  • For local single-user desktop applications, apply the proportional threat-model guidance in references/desktop-apps.md instead of importing server-grade assumptions by default

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.