-
Notifications
You must be signed in to change notification settings - Fork 418
Configuration for Static Code Checkers
When helping the Checkstyle project migrate from Commons CLI to picocli, we found that static code checkers will generate a number of "false positive" warnings for idiomatic picocli code, since fields annotated with @Option
, @Parameters
or @Spec
appear to never be assigned a value, other than the initial value. This causes a number of warnings, most commonly these:
-
"field never written", "field can be final": the static code checker is not aware that picocli will inject values into these fields with reflection
-
"unused field", especially for boolean fields for
@Option(names = "--help")
or@Option(names = "--version")
: these fields appear to never even be read by the application - you may be interested in using the@Command(mixinStandardHelpOptions = true)
annotation to avoid the need to declare these fields altogether.
The Checkstyle project applies all of its rules to its own code, and on top of that checks its own source with a combination of Intelli/J Idea inspections, PMD checks and Spotbug checks.
Below we will show some common issues and how to configure the static code checker to suppress spurious warnings.
The Checkstyle configuration enables many Intelli/J inspections, some of which are false positives in this case. For example, in a CLI application it is normal to write to System.out
and System.err
. The inspections also caught that there was a List
field that was queried while nowhere in the code values were added to this list: the List<File>
positional parameters populated by picocli.
Intelli/J inspections can be suppressed in comments in the source code:
/**
* Wrapper command line program for the Checker.
* @noinspection UseOfSystemOutOrSystemErr, unused, FieldMayBeFinal, CanBeFinal,
* MismatchedQueryAndUpdateOfCollection
**
@Command(name = "checkstyle", description = "...")
public final class Main
Spotbugs configuration to suppress false positive warnings:
<FindBugsFilter>
<Match>
<!-- false-positive: field values are injected by picocli -->
<Or>
<Class name="com.puppycrawl.tools.checkstyle.Main"/>
<Class name="com.puppycrawl.tools.checkstyle.JavadocPropertiesGenerator"/>
</Or>
<Or>
<Bug pattern="NP_UNWRITTEN_FIELD"/>
<Bug pattern="UWF_UNWRITTEN_FIELD"/>
<Bug pattern="MS_SHOULD_BE_FINAL"/>
<Bug pattern="MS_SHOULD_BE_REFACTORED_TO_BE_FINAL"/>
<Bug pattern="SS_SHOULD_BE_STATIC"/>
</Or>
</Match>
...
Out of the box, PMD knows it should not apply its "ImmutableField" and "UnusedPrivateField" rules to fields annotated with Lombok annotations. However, it is not (yet? PR, anyone?) picocli-aware, so you’ll need to explicitly ignore the picocli annotations:
<rule ref="category/java/design.xml/ImmutableField">
<property name="ignoredAnnotations"
value="picocli.CommandLine.Option
|picocli.CommandLine.Parameters
|picocli.CommandLine.Spec"/>
</rule>
<rule ref="category/java/bestpractices.xml/UnusedPrivateField">
<property name="ignoredAnnotations"
value="picocli.CommandLine.Option
|picocli.CommandLine.Parameters
|picocli.CommandLine.Spec"/>
</rule>