NonNull type annotation and checker

This document describes the @NonNull type annotation, and a checker for it.

The @NonNull type annotation indicates that a variable should never have a null value. The plugin issues a warning whenever a variable with the @NonNull annotation may become null. The example shows two ways this might happen: by being assigned null directly, or by being assigned the value of a possibly-null variable.

  @NonNull Object nnobj;
           Object   obj;  // might be null
  nnobj = null;  // checker will warn that nnobj will become null
  nnobj = obj;   // checker will warn that nnobj may become null

Parameter passing and return values are checked analogously to assignments.

Suppose that the plugin issues no warnings for a given program. Then running that program will never yield a null pointer exception as a result of dereferencing a variable whose type is annotated with @NonNull. This guarantee is very useful to programmers who wish to prevent errors from occurring when their programs are run in the field.

The plugin itself is built on the checkers framework and is implemented in the checkers.nonnull package.

The @NonNull annotation described in this document is similar, but not identical, to the @NotNull annotation of IntelliJ IDEA, the @NonNull annotation of FindBugs, and annotations proposed by JSR 305.

Example use

Tiny examples

To try the @NonNull plugin on a source file that uses the @NonNull qualifier, use the following command (where javac is the JSR 308 compiler):


  javac -typeprocessor checkers.nonnull.NonnullChecker examples/NonNullExample.java 

Compilation should complete successfully. To show an example of the checker warning about incorrect usage of annotations (and therefore the possibility of a null pointer exception at run time), use the following command:


  javac -typeprocessor checkers.nonnull.NonnullChecker examples/NonNullExampleWithWarnings.java 

The compiler should issue three warnings regarding violation of the semantics of @NonNull in the NonNullExampleWithWarnings.java file.

Annotated library

You can also run the nonnull checker on the annotation scene library, a larger library that has been fully annotated with @NonNull. To run the nonnull checker on the annotation scene library, first download the scene library suite (which includes build dependencies for the scene library as well as its source code) and extract it into your checkers installation. The checker can then be run on the annotation scene library with Apache Ant using the following commands:


  cd $CHECKERS
  ant -f scene-lib-test.xml

where $CHECKERS is the location of the checkers installation.

You can view the annotated source code, which contains @NonNull annoations, in the checkers/scene-lib-test/src/annotations/ directory.

Checking against unannotated code

The @NonNull plugin reads annotations that appear in the source code or .classfiles of classes that are used by the code being compiled and checked. If annotated code uses unannotated code (e.g., libraries or the JDK), then the checker may issue warnings whenever a library call result is used in a non-null context:

  @NonNull myvar = library_call();   // WARNING: library_call is not known to return a non-null value

To avoid such warnings, you need to annotate library methods with @NonNull.

The annotation file utilities can move annotations from a text file into class files. This allows a programmer to add annotations to a library without requiring the library source code.

Alternatively, when checking against the JDK, the @NonNull plugin honors the Java property checkers.skipSystemClasses. When this property is set to true (which is the default), the plugin will suppress reporting errors and warnings pertaining to classes in the java package. (To disable this behavior, set the property to false, e.g., by supplying the option “-Dcheckers.skipSystemClasses=false” when invoking javac.) Eventually, we will distribute a full set of @NonNull annotations for the JDK, so that this will not be necessary.