Rules
Stable
- Array equals - Array comparisons using == or equals() (
ARRAY_EQUALS) - AutoCloseable not closed - Locally created AutoCloseable instances should be closed on every exit path (
AUTOCLOSEABLE_NOT_CLOSED) - BigDecimal divide without rounding - BigDecimal.divide(BigDecimal) can throw on non-terminating decimals (
BIGDECIMAL_DIVIDE_WITHOUT_ROUNDING) - BigDecimal equals call - BigDecimal.equals compares value and scale instead of numeric equality (
BIGDECIMAL_EQUALS_CALL) - BigDecimal from double - BigDecimal constructors with double can introduce precision surprises (
BIGDECIMAL_FROM_DOUBLE) - BigDecimal setScale without rounding - BigDecimal.setScale(int) can throw when rounding is required (
BIGDECIMAL_SET_SCALE_WITHOUT_ROUNDING) - Boolean.getBoolean call - Boolean.getBoolean reads system properties, not text booleans (
BOOLEAN_GETBOOLEAN_CALL) - compareTo integer subtraction overflow - compareTo using integer subtraction can overflow for extreme values (
COMPARETO_OVERFLOW) - Coroutine context with Job - Coroutine builder and withContext calls that pass a CoroutineContext containing a Job element break structured concurrency (
COROUTINE_CONTEXT_WITH_JOB) - Coroutines call with raw Long milliseconds - kotlinx.coroutines time-based calls that pass a raw Long milliseconds value should use the kotlin.time.Duration overload when it is available on the classpath (
COROUTINES_LONG_MILLIS_CALL) - File.deleteOnExit call - File.deleteOnExit can accumulate pending deletions in long-lived processes (
DELETE_ON_EXIT_CALL) - ObjectInputStream deserialization call - readObject/readUnshared are high-risk Java deserialization entry points (
DESERIALIZATION_READ_OBJECT_CALL) - Empty catch block - Catch blocks with no meaningful instructions (
EMPTY_CATCH) - Exception cause not preserved - Catch handlers that throw new exceptions without preserving the cause (
EXCEPTION_CAUSE_NOT_PRESERVED) - ExecutorService not shut down - Locally created executor services should be shut down on every exit path (
EXECUTOR_SERVICE_NOT_SHUTDOWN) - Explicit finalize call - Direct virtual calls to finalize() bypass GC lifecycle and indicate broken resource cleanup (
EXPLICIT_FINALIZE_CALL) - Explicit GC call - Direct calls to explicit GC APIs should be avoided (
EXPLICIT_GC_CALL) - Future.get without timeout - Timeout-free Future.get calls can block indefinitely (
FUTURE_GET_WITHOUT_TIMEOUT) - Future wait while holding lock - Blocking Future waits should not happen while a lock is still held (
FUTURE_WAIT_WHILE_HOLDING_LOCK) - Ineffective equals/hashCode - Classes with equals without hashCode or vice versa (
INEFFECTIVE_EQUALS_HASHCODE) - Insecure API usage - Calls to insecure process or reflection APIs (
INSECURE_API) - Integer.getInteger call - Integer.getInteger reads system properties, not numeric input strings (
INTEGER_GETINTEGER_CALL) - InterruptedException not properly handled - Restore interrupt status when catching InterruptedException (
INTERRUPTED_EXCEPTION_NOT_RESTORED) - Koin AutoCloseable not closed - Koin singleton definitions that construct AutoCloseable resources should close them via onClose (
KOIN_AUTOCLOSEABLE_NOT_CLOSED) - Lock acquired without guaranteed release - Lock.lock() must be followed by unlock() on every reachable exit path (
LOCK_NOT_RELEASED_ON_EXCEPTION_PATH) - Log4j2 format should be const - Log4j2 format strings should be compile-time constants (
LOG4J2_FORMAT_SHOULD_BE_CONST) - Log4j2 illegal passed class - LogManager.getLogger should be called with the caller class (
LOG4J2_ILLEGAL_PASSED_CLASS) - Log4j2 logger should be final - Log4j2 Logger fields should be final (
LOG4J2_LOGGER_SHOULD_BE_FINAL) - Log4j2 logger should be private - Log4j2 Logger fields should be private (
LOG4J2_LOGGER_SHOULD_BE_PRIVATE) - Log4j2 preformatted message - Log4j2 messages should use placeholders instead of manual formatting (
LOG4J2_MANUALLY_PROVIDED_MESSAGE) - Log4j2 placeholder-only format - Log4j2 format strings should include descriptive text (
LOG4J2_SIGN_ONLY_FORMAT) - Log4j2 unknown array - Log4j2 varargs calls with unknown argument arrays (
LOG4J2_UNKNOWN_ARRAY) - Long.getLong call - Long.getLong reads system properties, not numeric input strings (
LONG_GETLONG_CALL) - Magic number - Numeric literals used directly in method bodies reduce readability and maintainability; extract them into named constants (
MAGIC_NUMBER) - Mutation on unmodifiable collection - Mutation calls on known JDK unmodifiable collection values (
MUTATE_UNMODIFIABLE_COLLECTION) - Nullness checks - Nullness issues guided by JSpecify annotations (
NULLNESS) - Object.wait without timeout - Timeout-free Object.wait calls can block indefinitely (
OBJECT_WAIT_WITHOUT_TIMEOUT) - Optional direct getter call - Optional.get/getAs* can throw when empty (
OPTIONAL_GET_CALL) - Prefer EnumSet for enum collections - Using EnumSet for enum types provides better performance than general collections (
PREFER_ENUMSET) - Direct printStackTrace call - Throwable.printStackTrace should be replaced with structured logging (
PRINT_STACK_TRACE) - Record array field - Records should not use array-typed components (
RECORD_ARRAY_FIELD) - Return in finally - Return statements in finally blocks override exceptions or prior returns (
RETURN_IN_FINALLY) - runBlocking in suspend function - runBlocking inside a suspend function blocks the calling thread and defeats asynchronous execution (
RUN_BLOCKING_IN_SUSPEND_FUNCTION) - runBlocking reachable from coroutine - runBlocking calls reachable from a coroutine through plain function calls block a shared coroutine thread (
RUN_BLOCKING_REACHABLE_FROM_COROUTINE) - Explicit finalization trigger call - System/Runtime runFinalization calls are unpredictable (
RUN_FINALIZATION_CALL) - Runtime.halt call - Direct Runtime.halt(int) calls bypass graceful JVM shutdown (
RUNTIME_HALT_CALL) - SLF4J format should be const - SLF4J format strings should be compile-time constants (
SLF4J_FORMAT_SHOULD_BE_CONST) - SLF4J illegal passed class - LoggerFactory.getLogger should be called with the caller class (
SLF4J_ILLEGAL_PASSED_CLASS) - SLF4J logger should be final - SLF4J Logger fields should be final (
SLF4J_LOGGER_SHOULD_BE_FINAL) - SLF4J logger should be private - SLF4J Logger fields should be private (
SLF4J_LOGGER_SHOULD_BE_PRIVATE) - SLF4J preformatted message - SLF4J messages should use placeholders instead of manual formatting (
SLF4J_MANUALLY_PROVIDED_MESSAGE) - SLF4J placeholder mismatch - SLF4J placeholder count does not match arguments (
SLF4J_PLACEHOLDER_MISMATCH) - SLF4J placeholder-only format - SLF4J format strings should include descriptive text (
SLF4J_SIGN_ONLY_FORMAT) - SLF4J unknown array - SLF4J varargs calls with unknown argument arrays (
SLF4J_UNKNOWN_ARRAY) - String case conversion without explicit locale - String.toLowerCase()/toUpperCase() calls without Locale argument (
STRING_CASE_WITHOUT_LOCALE) - String/Formatter formatting without explicit locale - String.format(...) and Formatter usage without Locale can vary by runtime locale (
STRING_FORMAT_LOCALE_MISSING) - String intern call - String.intern can increase global pool pressure and contention (
STRING_INTERN_CALL) - String trim followed by isEmpty - String.trim().isEmpty() can be ambiguous; prefer String.isBlank() (
STRING_TRIM_IS_EMPTY) - System.exit call - Direct calls to System.exit(int) terminate the JVM abruptly (
SYSTEM_EXIT) - Thread.run direct call - Direct Thread.run() calls execute synchronously on the current thread (
THREAD_RUN_DIRECT_CALL) - Thread.sleep call - Thread.sleep introduces timing-coupled blocking (
THREAD_SLEEP_CALL) - Unused lambda parameter - Reports lambda parameters that are never referenced in the lambda body (
UNUSED_LAMBDA_PARAMETERS) - URL equals call - URL.equals may trigger host resolution and surprising equality semantics (
URL_EQUALS_CALL) - URL hashCode call - URL.hashCode may trigger host resolution and surprising hash semantics (
URL_HASHCODE_CALL) - URL.openStream call - URL.openStream can hide timeout and connection configuration (
URL_OPENSTREAM_CALL) - Non-atomic update on volatile field - Read-modify-write updates on volatile fields can lose concurrent updates (
VOLATILE_INCREMENT_NON_ATOMIC)