Description
A typical Spring Boot application will tend to have a class that looks like
@SpringBootApplication
public class App {
public static void main(final String[] args) {
SpringApplication.run(App.class, args);
}
}
where delightful Spring magic relies on implicit extensibility to run the application. Crucially, it does not work with a private constructor or when the class is final.
For the code above, in v2.36.0, PrivateConstructorForUtilityClass
produces this false positive violation:
$ ./mvnw clean test-compile -DepFlags='-XepDisableAllChecks -Xep:PrivateConstructorForUtilityClass:ERROR'
[INFO] Scanning for projects...
...
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /.../src/main/java/example/App.java:[7,8] [PrivateConstructorForUtilityClass] Classes which are not intended to be instantiated should be made non-instantiable with a private constructor. This includes utility classes (classes with only static members), and the main class.
(see https://errorprone.info/bugpattern/PrivateConstructorForUtilityClass)
Did you mean 'public final class App {'?
With an explicit public constructor, PrivateConstructorForUtilityClass
shuts up and Spring Boot still works. However, I find that people tend to get confused by explicit public no-op constructors, and some linters flag them as redundant (incorrectly, IMO).
Although users can easily work around this false positive it would be nice if PrivateConstructorForUtilityClass
could learn to recognize the @SpringBootApplication
annotation.