Search code examples
javachecker-framework

Checker Framework initialization.fields.uninitialize false positive


Here's my error

  found   : @Initialized @Nullable String
  required: @Initialized @NonNull String
/Users/calebcushing/IdeaProjects/ppm/scaf/src/main/java/com/xenoterracide/scaf/Application.java:21: error: [initialization.fields.uninitialized] the constructor does not initialize fields: arg, args, dir
public final class Application implements Runnable {
             ^
3 errors

These are initialized by picocli, so I added SuppressWarnings, not certain why it's still happening.

  @SuppressWarnings({ "NullAway.Init", "initialization.fields.uninitialize" })
  @CommandLine.Parameters( index = "0", description = "first configuration directory" )
  private String arg;

  @SuppressWarnings({ "NullAway.Init", "initialization.fields.uninitialize" })
  @CommandLine.Parameters(
    index = "1..*",
    description = "path to configuration directories separated by space"
  )
  private List<String> args;

  @SuppressWarnings({ "NullAway.Init", "initialization.fields.uninitialize" })
  @CommandLine.Option(
    names = {"-d", "--dir"},
    defaultValue = ".config/scaf",
    showDefaultValue = CommandLine.Help.Visibility.ALWAYS,
    description = "Directory path from the current working directory. " +
      "Templates and configs are looked up relative to here"
  )
  private Path dir;

I've tried putting

  @SuppressWarnings({ "NullAway.Init", "initialization.fields.uninitialize"})

on the class, the constructor and as you can see, the field. How do I make checkerframework happy?

here is the full source code checker framework is not currently enabled in it due to the fact this wouldn't compile if I did.


Solution

  • Checker framework is complaining because in your main method you are not initializing the instance fields arg, args and dir. If you not annotate a field explicitly, for the checker framework point of view, the field is considered to be @NotNull.

    Please, try to annotate that fields with @Nullable:

      @CommandLine.Parameters( index = "0", description = "first configuration directory" )
      private @Nullable String arg;
    
      @CommandLine.Parameters(
        index = "1..*",
        description = "path to configuration directories separated by space"
      )
      private @Nullable List<String> args;
    
      @CommandLine.Option(
        names = {"-d", "--dir"},
        defaultValue = ".config/scaf",
        showDefaultValue = CommandLine.Help.Visibility.ALWAYS,
        description = "Directory path from the current working directory. " +
          "Templates and configs are looked up relative to here"
      )
      private @Nullable Path dir;
    

    Although you configured picocli to provide default values, checker framework only knows that after the main method invocation these fields are not initialized, there is no such initialization code, picocli will provide the default value you indicated but checker framework is not aware of that, that is why it is complaining about it.

    Having said that, if you prefer to suppress warnings, please, be aware that checker framework is indicating the warning type that must be suppressed, initialization.fields.uninitialized, and it seems you have a typo in the code:

    @SuppressWarnings({ "NullAway.Init", "initialization.fields.uninitialize" })
    

    Please, note the difference between the required value, initialization.fields.uninitialized, and the one you provided, initialization.fields.uninitialize.