java:S1258 fails to handle lombok's `@UtilityClass` together with static initializers

  • Language: Java
  • Rule: java:S1258 “Classes and enums with private fields should have a constructor”
  • Running SonarLint 10.4.0.82051 under Eclipse 2024-06 (4.32) together with lombok v1.18.32

Consider the following snippet:

@lombok.experimental.UtilityClass
public class Foo {
	private final String bar; // Implicitly static because of @UtilityClass
	
	static {
		bar = "bar";
	}
}

The rule wrongly marks the class declaration as needing a constructor in order to initialize the field bar, which is static because of @UtilityClass and is already initialized in the static initializer.

The warning disappears if the field has visibility other than private (including package-private), or if the field is explicitly marked as static (which is redundant with the annotation’s purpose), which means that the rule is disregarding @UtilityClass and thinking that the field bar is not static.

This false positive may be related to this one about @Builder and @SuperBuilder and this one also about those annotations.

Hello @ivaniesta14!

The @UtilityClass annotation is an experimental feature in Lombok, and it doesn’t look like it will become stable any time soon. It looks like there is some controversy around it among the Lombok maintainers, since declaring a field non-static but making it static implicitly causes some issues (see the “experimental because” section in the documentation page of that feature).

I think we should not support this feature before it becomes stable. What you can do in the meantime:

  1. Suppress the warning in the source code or disable the rule,
  2. Mark as “accept / won’t fix” or “false positive” in SonarQube
  3. Use the @UtilityClass annotation only to automatically create the constructor and declare the fields static explicitly:
@lombok.experimental.UtilityClass
public class Foo {
  private static final String BAR = "bar";
}

Best,
Marco