I use Sonarqube 5.1 and experiment with the “Sonar way” Java quality profile. The job is simple: I want to define a global String constant for a missing media type:
public interface Utf8MediaType {
String APPLICATION_JSON = "application/json;charset=UTF-8";
}
However, Sonarqube tells me this is bad practice in rule squid:S1214 – Constants should not be defined in interfaces. The long text talks about implementing this interface, which I didn’t intend to, but I give in and create a class instead:
public class Utf8MediaType {
public static final String APPLICATION_JSON = "application/json;charset=UTF-8";
}
However, this is considered to be a major design issue in rule squid:S1118 – Utility classes should not have public constructors. So it’s urging me to add a private constructor. Of course, this constructor has then to come first not to violate conventions in rule squid:S1213 – The members of an interface declaration or class should appear in a pre-defined order. I guess after that I might even get common-java:InsufficientBranchCoverage because the private constructor is not covered in tests.
These are the default rules and I feel they are a bit silly in combination. I have more examples where the defaults just don’t work for us (TestNG support is lacking). What can I do about it? What do you recommend?
- Give in. Make it a class, add a private constructor, use introspection in the unit test. Makes the code ten times as big. For a String constant.
- Create a list of exceptions. But doing this for each project may lead to long lists and invites people to add exceptions even for important stuff.
- Deactivate rules. Now I would prefer not to tamper with the default profiles, because that may mean a lot of work on Sonarqube upgrades.
- Create a profile that inherits from the default and overwrites things. It turns out that when you inherit from a profile you cannot deactivate rules. You can only add additional rules and change the configuration of rules (to lower their severity).