SONARJAVA-6464 Fix S2119 false positive for chained Random() in field initializers#5831
Conversation
Tests cover the scenario where new Random() is used as the receiver of a chained method call in a static or instance field initializer (e.g., static IntStream s = new Random().ints(100)). The rule incorrectly flags these cases because isInConstructorOrStaticMain() returns false when getEnclosingMethod() is null (field initializer context). The tests verify that field initializers with chained Random() calls are treated as compliant, matching both static and instance field initializer patterns. Relates to SONARJAVA-6464
S2119 was incorrectly flagging `new Random()` used in field initializers with chained method calls (e.g., `static IntStream s = new Random().ints(100)`). The root cause was that `isInConstructorOrStaticMain()` returned `false` when `getEnclosingMethod()` returned `null` (field initializer context), while `isUsedOnlyLocally()` correctly returned `true` for the chained `MEMBER_SELECT` parent, causing a false positive. The fix renames the method to `isEffectivelyOneTimeInitialized()` and returns `true` when `getEnclosingMethod()` is `null`, covering field initializers, static initializer blocks, and instance initializer blocks — all contexts where the `Random` is a one-time class-level initialization. The rspec exceptions section is updated to reflect this behavior. Relates to SONARJAVA-6464
Rule Profile
Genuine violation (a new void doSomething() {
new Random().ints(100).forEach(System.out::println); // Noncompliant
}False Positive PatternWhen public class Example {
// Flagged before the fix — compliant, Random is created once at class-load time
static IntStream s = new Random().ints(100);
}Direct field assignment (non-chained) was already handled correctly: its AST parent is False Negative RiskThe fix suppresses issues for any Fix Summary
|
|




Relates to SONARJAVA-6464
S2119 incorrectly flagged
new Random()when it was used as the receiver of a chained method call in a field initializer (e.g.,static IntStream s = new Random().ints(100)). The fix extends the initialization-context guard to treat any code with no enclosing method or constructor as a one-time class-level initialization, covering field initializers, static initializer blocks, and instance initializer blocks.isEffectivelyOneTimeInitialized()now returnstruewhengetEnclosingMethod()isnull, which previously short-circuited tofalseand triggered the false positivestatic Random f = new Random()) were already exempt; only the chained form was affectedmain