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
- Distinctive: line 29
Start from the concrete failure and change the narrowest responsible boundary.
- Distinctive: line 30
Do not redesign neighboring subsystems unless the user explicitly approves that expanded scope.
- Distinctive: line 31
Prefer a local method or class change over a new service, framework, protocol, ownership model, or lifecycle abstraction.
- Distinctive: line 33
Before adding more than a few production types or crossing subsystem boundaries, pause and present the simpler alternative and regression …
- Distinctive: line 35
Do not add production APIs or hooks solely to simulate implausible failures in tests.
- Distinctive: line 36
Do not preserve failed approaches as compatibility scaffolding.
- Distinctive: line 37
After two unsuccessful or unverified attempts at the same issue, stop iterating.
- Distinctive: line 38
Before completion, audit the whole diff and remove speculative limits, dead helpers, duplicate lifecycle paths, unused dependencies, and …
- Distinctive: line 46
Always prefer simple class names over fully qualified names — add an import instead:
- Very specific: line 49
Keep the owning type when it adds important meaning.
- Very specific: line 56
Prefer empty-collection factory methods over List/Map/Set.of() for empty collections:
- Very specific: line 58
Prefer List.of(array) over Arrays.asList(array)
- Very specific: line 59
Never use Optional as a method parameter or class field — it is exclusively a return type
- Distinctive: line 65
If Apache Commons Lang v3+ is already on the classpath, use it heavily and actively across the codebase.
- Distinctive: line 73
If Lombok is already on the classpath, use it heavily and actively across the codebase to eliminate boilerplate.
- Very specific: line 83
Prefer String.formatted(...) over + string concatenation
- Very specific: line 84
Prefer stream-based functional iteration over for/while loops
- Very specific: line 85
Prefer the ternary operator or a switch expression over if statements where it improves clarity
- Distinctive: line 86
Prefer method references over equivalent lambdas when the lambda only forwards its argument to a single method or constructor:
- Distinctive: line 91
Keep the lambda form when it adds logic (extra arguments, transformation, multiple statements) — readability wins over terseness
- Very specific: line 92
Prefer functional interface composition (Function.andThen / compose, Consumer.andThen, Predicate.and / or / negate / Predicate.not) over …
- Very specific: line 114
When overriding, include non-sensitive fields normally and replace sensitive values with a fixed mask like "".
- Distinctive: line 120
Prefer small, single-purpose methods over large, multi-purpose methods.
- Distinctive: line 129
Keep method declarations and invocations on a single line when they fit reasonably
- Very specific: line 130
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 …
- Distinctive: line 176
Never impose personal formatting preferences.
- Distinctive: line 180
Use the java-coder and test-coverage skills if available
- Distinctive: line 183
Always use AssertJ — never raw JUnit assertions
- Very specific: line 191
Prefer @InjectMocks over constructing the tested class manually in @BeforeEach
- Very specific: line 192
Prefer var for locals initialized by a constructor or builder call
- Distinctive: line 201
Never hardcode credentials, secrets, or tokens — use an appropriate external credential source or secure application-owned store
- Distinctive: line 204
Keep security concerns consistent across the stack.
≈ “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.
Files
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), orcatch (Throwable cause)to avoid name conflicts
- or
- Exception: catch-block variables should be a single character by default (e.g.,
- 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()orjoining() - Keep the owning type when it adds important meaning; never statically import methods from
Optional,Validate,StringUtils, orArrays— writeOptional.empty(),Validate.notBlank(...),StringUtils.isBlank(...), andArrays.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)overArrays.asList(array) - Never use
Optionalas 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/whileloops - Prefer the ternary operator or a
switchexpression overifstatements 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 existingFunction,Consumer, orPredicatevalues — seereferences/functional-composition.mdfor 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 |
varis freely allowed in tests at the author's discretion
Sensitive Data & record Classes
- Do not override
toStringby default inrecordclasses — use the generated implementation unless the record contains sensitive, secret, or PII data - Override
toStringonly 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
- Fields to mask include (but are not limited to):
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
| Concern | Choice |
| Language | Java 21+ — use modern features (records, sealed classes, patterns) |
| Framework | Spring Boot — match the project version; follow Spring idioms |
| Build | Maven (preferred) or Gradle |
| Persistence | JPA/Hibernate · PostgreSQL · H2 (tests) |
| Testing | JUnit 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:
.editorconfig— if present at the project root, it takes precedence for indent style, indent size, line endings, and charset- IDE code style settings — check for exported scheme files:
- IntelliJ IDEA (preferred):
.idea/codeStyles/,*.xmlschemes, orProject.xml - Eclipse:
.settings/org.eclipse.jdt.core.prefsor a.xmlformatter profile
- IntelliJ IDEA (preferred):
- 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
@InjectMocksover constructing the tested class manually in@BeforeEach - Prefer
varfor 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,
@Configurationbeans, 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.mdinstead of importing server-grade assumptions by default
In this repository31 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- architectSkill
- arenaSkill
- blast-radiusSkill
- brainstormSkill
- broSkill
- clarifySkill
- code-reviewSkill
- debug-errorSkill
- diagram-designSkill
- execution-verificationSkill
- explain-codeSkill
- in-your-own-wordsSkill
- ketchupSkill
- owasp-securitySkill
- pdfSkill
- pretty-mermaidSkill
- refactor-codeSkill
- reflectSkill
- sharpenSkill
- skill-hunterSkill
- tddSkill
- teachSkill
- technical-writingSkill
- test-coverageSkill
- typesafe-aiSkill
- typescript-coderSkill
- unslopSkill
- write-testsSkill
- wrongSkill
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
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.

