feat(rules-java): expand language guidance
This commit is contained in:
1 parent
30a6a4e51d
commit
0a8a54bf99
9 files changed
+90
-14
No files matched your search
@@ -1,8 +1,14 @@
|
||||
# Java Rules
|
||||
|
||||
For Java or JVM work, open only the topic rules relevant to the task. Follow the project's target Java release and conventions, and load applicable shared security rules as well.
|
||||
For Java or JVM work, open only the topic rules relevant to the task. Follow the project's target Java release, compiler settings, and conventions. Load applicable shared security rules as well. Avoid preview APIs unless the project explicitly enables them.
|
||||
|
||||
| Topic | Codex rule | Claude skill |
|
||||
| --- | --- | --- |
|
||||
| Modern Java and coding style | `references/modern-java.md` | `rules-java-modern-java` |
|
||||
| Language style and code organization | `references/modern-java.md` | `rules-java-modern-java` |
|
||||
| Types, collections, and null-safe contracts | `references/types-and-collections.md` | `rules-java-types-and-collections` |
|
||||
| Architecture and API boundaries | `references/architecture-and-apis.md` | `rules-java-architecture-and-apis` |
|
||||
| Async work and concurrency | `references/async-and-concurrency.md` | `rules-java-async-and-concurrency` |
|
||||
| Performance | `references/performance.md` | `rules-java-performance` |
|
||||
| Security | `references/security.md` | `rules-java-security` |
|
||||
| Validation, errors, and logging | `references/safety-and-errors.md` | `rules-java-safety-and-errors` |
|
||||
| Tests, dependencies, and build diagnostics | `references/testing-and-dependencies.md` | `rules-java-testing-and-dependencies` |
|
||||
@@ -0,0 +1,11 @@
|
||||
# Java Architecture and APIs
|
||||
|
||||
Apply these rules when designing public APIs, service boundaries, or application structure.
|
||||
|
||||
* Give APIs explicit request, response, and error contracts. Validate external input at the boundary without scattering redundant checks through trusted internal code.
|
||||
* Separate transport models, domain models, and persistence entities. Accept only fields callers may set and return only fields they may read.
|
||||
* Authorize the specific resource and operation where data is accessed or changed. Preserve ownership and tenant scope across alternate paths and background work.
|
||||
* Bound payloads, page sizes, query complexity, and operation cost. Use pagination or streaming for potentially large results.
|
||||
* Keep domain decisions separate from transport, persistence, and framework wiring. Make dependencies explicit; use dependency injection for real lifecycle or substitution needs.
|
||||
* Prefer composition and small contracts at real boundaries. Avoid service locators, broad base classes, reflection, and wrappers without a concrete purpose.
|
||||
* Preserve existing API and serialization behavior unless the task requires a change. Treat changes to nullability, ordering, exception types, and collection mutability as compatibility changes.
|
||||
@@ -0,0 +1,12 @@
|
||||
# Java Async and Concurrency
|
||||
|
||||
Apply these rules when changing executors, threads, futures, background work, or shared state.
|
||||
|
||||
* Choose synchronous, asynchronous, platform-thread, or virtual-thread execution for the actual workload and target Java release. Virtual threads suit many blocking I/O tasks; they do not accelerate CPU work.
|
||||
* Keep task lifetime owned by a request, service, or scoped executor. Close or shut down owned executors and handle completion, failure, timeout, and cancellation.
|
||||
* Propagate interruption and cancellation. When catching `InterruptedException` without rethrowing it, restore the interrupt flag and stop work safely; do not turn cancellation into success.
|
||||
* Bound queues, fan-out, and downstream calls. Virtual threads reduce thread cost but do not remove database, network, memory, or rate limits.
|
||||
* Protect shared mutable state with clear ownership or suitable concurrency primitives. Do not assume `volatile` makes compound actions atomic.
|
||||
* Avoid blocking joins inside unrelated executor tasks when they can exhaust a bounded pool. Use `CompletableFuture` or parallel streams only when their execution context and failure behavior are understood.
|
||||
* Keep retries limited to transient failures, with bounded attempts and delay. Preserve idempotency and avoid retry multiplication across layers.
|
||||
* Use preview concurrency APIs only when the project explicitly enables them for its target release.
|
||||
@@ -1,12 +1,12 @@
|
||||
# Modern Java
|
||||
# Java Coding Style
|
||||
|
||||
Apply these rules when writing or reviewing Java code.
|
||||
Apply these rules when editing Java syntax, class structure, and everyday code organization.
|
||||
|
||||
* Match the project's configured Java release, compiler flags, libraries, and style. Use newer language or library features only when that release supports them and they improve clarity.
|
||||
* Prefer clear, immutable value types. Use records for transparent data carriers and sealed types when a closed set of variants is part of the domain; do not force these forms onto mutable entities or framework-bound types.
|
||||
* Use pattern matching, switch expressions, and text blocks where supported and clearer than older forms. Keep control flow explicit; streams are not automatically clearer or faster than loops.
|
||||
* Prefer local `var` only when the initializer makes the type obvious. Keep public APIs explicitly typed and avoid raw types and unchecked casts.
|
||||
* Keep classes and methods focused, use descriptive names, and make state and side effects easy to see. Prefer composition and small interfaces at real boundaries over speculative abstractions.
|
||||
* Use try-with-resources for `AutoCloseable` resources. Preserve interruption, exception causes, and precise failure context; do not swallow exceptions or use exceptions for ordinary control flow.
|
||||
* Define nullability and mutability expectations at API boundaries. Prefer standard collection and `Optional` conventions without using `Optional` for fields or parameters by default.
|
||||
* Avoid deprecated APIs and obsolete date/time or concurrency utilities when supported standard replacements fit the target release. Remove dead code and unused dependencies.
|
||||
* Match the project's Java release, style, and framework conventions. Use newer syntax only when supported and clearer.
|
||||
* Prefer direct control flow and descriptive domain names. Use streams when they clarify a transformation; loops are often clearer for stateful work or error handling.
|
||||
* Use local `var` only when the initializer makes the type obvious. Keep public contracts explicitly typed.
|
||||
* Use records for transparent immutable carriers and sealed types for genuinely closed variants when the target release supports them. Do not force them onto mutable entities or framework-managed types.
|
||||
* Prefer composition and focused classes over inheritance, reflection, global mutable state, or speculative interfaces.
|
||||
* Make ownership, mutation, and side effects visible. Use `final` where it clarifies invariants; do not add it mechanically to every local variable.
|
||||
* Prefer supported `java.time` APIs and standard library facilities over obsolete APIs or custom helpers when they fit the contract.
|
||||
* Remove dead code. Add comments only for non-obvious decisions or public contracts that code cannot express clearly.
|
||||
@@ -5,8 +5,10 @@ Apply these rules when optimizing Java runtime, memory, or throughput.
|
||||
* Measure a representative workload on the target JDK and deployment configuration before optimizing. Profile first; distinguish startup, steady-state latency, tail latency, throughput, allocation, GC, and memory costs.
|
||||
* Prioritize algorithmic complexity, database and network round trips, I/O, contention, allocation and GC, then instruction-level work. Fix the dominant cost rather than tuning by intuition.
|
||||
* Choose collections and algorithms for actual access patterns and data growth. Avoid repeated scans, needless sorting or copying, unbounded results, and N+1 data access.
|
||||
* Filter and project in the data source when appropriate; avoid materializing rows or fields that the caller does not use. Bound page sizes and query work.
|
||||
* Stream or process data in bounded chunks when whole-input buffering can exhaust memory. Bound queues, caches, thread pools, and parallel work to the capacity of downstream systems.
|
||||
* Reduce allocation in profiled hot paths. Avoid premature object pooling, custom caches, and low-level tricks; pooling can retain memory or leak mutable state.
|
||||
* Use concurrency only when it improves measured end-to-end throughput or latency. Account for ordering, cancellation, backpressure, contention, and failure handling.
|
||||
* Reduce allocation and boxing in profiled hot paths. Avoid premature object pooling, custom caches, and low-level tricks; pooling can retain memory or leak mutable state.
|
||||
* Cache only when repeated work is measured and key, lifetime, invalidation, size limit, and sensitive-data handling are explicit.
|
||||
* Use concurrency only when it improves measured end-to-end throughput or latency. Account for ordering, cancellation, backpressure, contention, and failure handling; virtual threads do not make CPU work faster.
|
||||
* Use JMH for JVM microbenchmarks when isolating small operations; prevent dead-code elimination and account for warmup, forks, and measurement variance. Use production-like profiling for system behavior.
|
||||
* Re-run the same workload after a change and compare correctness, CPU, allocation, GC, memory, latency, and throughput. Keep the simplest implementation that meets the measured goal.
|
||||
@@ -0,0 +1,11 @@
|
||||
# Java Safety and Error Handling
|
||||
|
||||
Apply these rules when handling external input, failures, resources, or logs.
|
||||
|
||||
* Validate size, range, format, and allowed values before expensive parsing, allocation, or side effects. Keep validation consistent with business and security constraints.
|
||||
* Reject null where a value is required, with clear argument or boundary validation. Do not hide invalid state behind default values that change behavior.
|
||||
* Use try-with-resources for owned `AutoCloseable` resources. Keep ownership explicit and do not close resources supplied by a caller unless the contract says so.
|
||||
* Catch only failures the current layer can handle. Preserve exception causes and useful context; do not swallow failures, catch broadly to continue with partial state, or use exceptions for routine control flow.
|
||||
* Preserve interruption and cancellation during error handling. Timeouts and retries need bounds and must not silently turn failure into success.
|
||||
* Use structured logs where the project supports them. Never log credentials, tokens, personal data, or unbounded payloads; avoid excessive logging in hot paths.
|
||||
* Return safe, consistent error information. Do not disclose protected resource existence or internal details to unauthorized callers.
|
||||
@@ -0,0 +1,12 @@
|
||||
# Java Security
|
||||
|
||||
Apply these rules to security-sensitive Java code. Load the focused shared security rule for each affected boundary as well.
|
||||
|
||||
* Validate untrusted input before expensive work and authorize the specific resource and operation. Java types and client-side validation do not establish trust.
|
||||
* Use parameterized database APIs such as `PreparedStatement`. Select dynamic identifiers or sort expressions from a fixed allowlist; never concatenate untrusted data into SQL.
|
||||
* Resolve file paths against an authorized root and account for symlinks and replacement races when an attacker can change the filesystem. Limit file size and processing work.
|
||||
* Use `ProcessBuilder` with an executable and separate arguments; avoid shell interpretation. Restrict executable paths and validate attacker-controlled arguments.
|
||||
* Deserialize into explicit allowed types. Avoid native Java serialization and unrestricted polymorphic type activation for untrusted data; bound input size and nesting.
|
||||
* Use the platform's maintained TLS, cryptographic, and secure-random APIs. Do not disable certificate validation or build custom cryptography.
|
||||
* Keep secrets out of source, logs, exception messages, and serialized responses. Use approved secret storage and clear ownership for sensitive data.
|
||||
* Use context-appropriate encoding for HTML, XML, and other interpreters. Test rejected, malformed, oversized, unauthorized, and cross-tenant inputs where relevant.
|
||||
@@ -0,0 +1,11 @@
|
||||
# Java Testing and Dependencies
|
||||
|
||||
Apply these rules when changing tests, build files, dependencies, or diagnostics.
|
||||
|
||||
* Write deterministic behavior-based tests for public contracts and failure paths. Avoid assertions tied to private call order, wall-clock timing, or uncontrolled external services.
|
||||
* Test null and empty cases, malformed input, resource cleanup, interruption, and concurrency behavior when those risks are affected. Use integration tests for actual persistence, framework, or serialization boundaries.
|
||||
* Keep production code testable through clear contracts and ownership. Do not add abstraction layers or production hooks solely for tests without a concrete need.
|
||||
* Prefer the JDK and existing supported libraries when they solve the problem. Keep dependencies minimal, maintained, and compatible with the configured Java release.
|
||||
* Respect the repository's Maven or Gradle dependency and plugin management. Review transitive changes, build plugins, and lockfiles; do not hand-edit generated dependency state.
|
||||
* Treat compiler warnings and configured static-analysis findings as actionable. Suppress a diagnostic only with a specific reason and narrow scope.
|
||||
* Run the focused tests and checks for the changed path; broaden verification when shared behavior, compatibility, or security is affected.
|
||||
@@ -0,0 +1,11 @@
|
||||
# Java Types and Collections
|
||||
|
||||
Apply these rules when defining type contracts, choosing collections, or handling nullable values.
|
||||
|
||||
* Write null-safe code. State whether each boundary value may be absent, validate required values before dereferencing, and use the project's nullability annotations and analysis tools when available. Do not assume an annotation enforces runtime validation.
|
||||
* Prefer non-null return values and empty collections for valid empty results. Use `Optional<T>` mainly for a return value that may have no result; do not return a null `Optional` or use it for fields and parameters by default.
|
||||
* Distinguish a missing map key from a key mapped to null when the contract permits both. Do not use `get()` alone when that distinction matters.
|
||||
* Keep public contracts strongly typed. Avoid raw types, unchecked casts, and stringly typed maps; document and narrowly suppress unavoidable generic warnings.
|
||||
* Choose `List`, `Set`, `Map`, or a more specific type according to ordering, uniqueness, lookup, and mutation needs. Expose only the capabilities callers need; do not leak mutable internal collections.
|
||||
* Distinguish an unmodifiable view from an independent copy. Make defensive copies at ownership boundaries when later mutation would violate the contract.
|
||||
* Prefer immutable data for values with stable identity and ownership, while respecting framework and serialization requirements. Avoid unnecessary boxing and copies in measured hot paths.
|
||||
Reference in new issue
Block a user