-
Notifications
You must be signed in to change notification settings - Fork 318
Configuration
The NullAway checker takes multiple configuration flags, in the format of Error Prone's Command-Line Flags. Before version 0.12.3, NullAway throws an error immediately upon loading if the -XepOpt:NullAway:AnnotatedPackages flag is not specified. In versions 0.12.3 and after, NullAway requires exactly one of either the -XepOpt:NullAway:AnnotatedPackages flag or the -XepOpt:NullAway:OnlyNullMarked flag (see below).
The following flags are currently supported; each of them can take multiple values as a comma separated list:
-XepOpt:NullAway:AnnotatedPackages=...
The list of packages that should be considered properly annotated according to the NullAway convention (every possibly null parameter / return / field annotated @Nullable). E.g., -XepOpt:NullAway:AnnotatedPackages=com.foo,org.bar.
This option supports restricted regexp syntax.
-XepOpt:NullAway:OnlyNullMarked=true
This option indicates that the AnnotatedPackages flag has been deliberately omitted, and that NullAway can proceed with only treating @NullMarked code as annotated, in accordance with the JSpecify specification. If this option is passed, the AnnotatedPackages flag cannot be passed. Note that even if this flag is omitted (and AnnotatedPackages is passed), any @NullMarked code will still be treated as annotated.
As JSpecify annotations become more widely adopted, eventually NullAway may remove this flag as it may become unnecessary.
-XepOpt:NullAway:UnannotatedSubPackages=...
A list of subpackages to be excluded from the AnnotatedPackages list. E.g., if all code under com.foo packages is properly annotated except for code under com.foo.baz, you could use the options -XepOpt:NullAway:AnnotatedPackages=com.foo -XepOpt:NullAway:UnannotatedSubPackages=com.foo.baz.
This option supports restricted regexp syntax.
-XepOpt:NullAway:UnannotatedClasses=...
A list of classes within annotated packages that should be treated as unannotated. E.g., if all code under com.foo should be treated as annotated except for the class com.foo.UnAnnot, you could use the options -XepOpt:NullAway:AnnotatedPackages=com.foo -XepOpt:NullAway:UnannotatedClasses=com.foo.UnAnnot.
-XepOpt:NullAway:KnownInitializers=...
The fully qualified name (without argument's, e.g. android.app.Activity.onCreate) of those methods from third-party libraries that NullAway should treat as initializers (equivalent to being annotated with an @Initializer annotation).
-XepOpt:NullAway:ExcludedClassAnnotations=...
A list of annotations that cause classes to be excluded from nullability analysis. Note that while NullAway does not analyze the code of these classes, it still assumes the APIs are annotated correctly when analyzing callers into methods of the classes.
-XepOpt:NullAway:ExcludedClasses=...
A list of classes to be excluded from the nullability analysis. Note that while NullAway does not analyze the code of these classes, it still assumes the APIs are annotated correctly when analyzing callers into methods of the classes.
-XepOpt:NullAway:ExcludedFieldAnnotations=...
A list of annotations that cause fields to be excluded from being checked for proper initialization (e.g. javax.inject.Inject).
This option supports restricted regexp syntax.
[Since 0.9.3]
Please note that NullAway requires no configuration to support any annotations with simple name @Nullable (such as javax.annotation.Nullable or androidx.annotation.Nullable) and natively supports a number of other common nullability annotations. The same is true for common variations of @NonNull, when relevant. See Supported Annotations.
There is also specific optional support for Android's "Recent" Nullability Annotations, which can be configured separately.
However, if your project uses annotations with non-standard names for nullability, which aren't part of a library NullAway is aware of, you can still specify them by using the following two configuration options:
-XepOpt:NullAway:CustomNullableAnnotations=...
A list of annotations that should be considered equivalent to @Nullable annotations. Note that any annotation with the simple name @Nullable, from any package, will be considered a nullable annotation (and thus doesn't need to be explicitly configured), but names passed to this configuration option must be fully-qualified class names.
-XepOpt:NullAway:CustomNonnullAnnotations=...
A list of annotations that should be considered equivalent to @NonNull annotations, for the cases where NullAway cares about such annotations (see e.g. AcknowledgeRestrictiveAnnotations). Note that any annotation with the simple name @NonNull, @NotNull, or @Nonnull, from any package, will be considered a non-null annotation (and thus doesn't need to be explicitly configured), but names passed to this configuration option must be fully-qualified class names.
-XepOpt:NullAway:CustomInitializerAnnotations=...
A list of annotations that should be considered equivalent to @Initializer annotations, and thus mark methods as initializers (e.g. org.junit.Before and org.junit.BeforeClass, which are automatically added to this list by default). Note that any annotation with the simple name @Initializer, from any package, will be considered an initializer annotation, but names passed to this configuration option must be fully-qualified class names.
-XepOpt:NullAway:ExternalInitAnnotations=...
A list of annotations for classes that are "externally initialized." Tools like the Cassandra Object Mapper do their own field initialization of objects with a certain annotation (like @Table), after invoking the zero-argument constructor.
For any class annotated with an external-init annotation, we don't check that the zero-arg constructor initializes all non-null fields.
Additionally, these external-init annotations will also be acknowledged if they annotate a zero-arg constructor directly, rather than the full class, with equivalent semantics to @SuppressWarnings("NullAway.Init") on that same constructor. Note, however, that external-init annotations will be ignored if they appear in non-zero arg constructors or non-constructor methods (e.g. initializers).
-XepOpt:NullAway:AssertsEnabled=...
By default, NullAway ignores assertions in the analyzed code. The reason for this is that assertions are not guaranteed to be checked at runtime.
Thus, in the following code:
T1 t1 = new T1();
assert t1.obj != null;
t1.obj.toString();
Whether t1.obj can or can't be null at the point toString() is called on it depends on the way the code is run and whether or not assert statements are being checked by the JVM (usually they are not in production runs). By default, NullAway assumes assert statements won't always be there at runtime, and thus it doesn't rely on nullness checks within assertions.
Setting AssertsEnabled=true overrides this behavior and makes NullAway assume that assertions will always be enabled at runtime (e.g. that the code will always be run with -enableassertions being passed to the JVM).
-XepOpt:NullAway:TreatGeneratedAsUnannotated=...
If set to true, NullAway treats any class annotated with @Generated as if its APIs are unannotated when analyzing uses from other classes. It also does not perform analysis on the code inside @Generated classes. If you can modify the code generator such that at least the APIs of @Generated classes are annotated correctly, we recommend using the -XepOpt:NullAway:ExcludedClassAnnotations option instead. Defaults to false.
-XepOpt:NullAway:CustomGeneratedCodeAnnotations=...
A list of annotations that should be considered as marking code as generated. Note that any annotation with the simple name @Generated, from any package, will be considered marking code as generated, but names passed to this configuration option must be fully-qualified class names. Useful in conjunction with the TreatGeneratedAsUnannotated option.
-XepOpt:NullAway:AcknowledgeRestrictiveAnnotations=...
This option adds some extra safety when dealing with third-party code that includes potentially incomplete nullability annotations. If set to true, NullAway will acknowledge nullability annotations whenever they are available in unannotated code and also more restrictive than it's optimistic defaults.
For example, when this flag is turned on, a method Object foo(Object o) in an unannotated package will still be assumed to take a nullable argument and return non-null (an optimistic assumption, made for usability reasons). However, a method Object bar(@NonNull Object o) will be interpreted by NullAway as taking a non-null argument, and a method @Nullable Object baz(Object o) will be acknowledged as potentially returning null, even in code otherwise marked as unannotated. If this flag is turned off, which is the default, all three examples are treated as the first and optimistic defaults are assumed to reduce the number of warnings unless the package is marked as fully annotated.
Note that e.g. an @NonNull annotation in annotated code is meaningless, whether or not this flag is set, as that's NullAway's default for that code. But this affects NullAway's handling of code marked as unannotated.
Also, specific method annotations can always be overridden by explicit Library Models, which take precedence over both the optimistic defaults and any annotations in the code, whether marked as annotated or unannotated.
-XepOpt:Nullaway:AcknowledgeAndroidRecent=...
If this flag is set to true and -XepOpt:Nullaway:AcknowledgeRestrictiveAnnotations is set to true, we treat the Android @RecentlyNullable annotation as @Nullable, and similarly for @RecentlyNonNull.
-XepOpt:NullAway:CastToNonNullMethod=[...]
Specifies the method being used for casting @Nullable expressions to @NonNull; see downcasting docs. When this option is passed, NullAway will emit a warning if a downcast is ever performed on an expression that is already @NonNull.
-XepOpt:NullAway:ExhaustiveOverride=...
By default, NullAway relies on the @Override annotation to know which methods override a super-type method and thus must be checked for consistency in the nullness of their return value and parameters. This is done for performance reasons.
In codebases where @Override is not used consistently, this flag should be set to true. It forces NullAway to check every method to see whether or not it overrides a method of a super-type.
-XepOpt:NullAway:CheckOptionalEmptiness=...
If set to true, NullAway will check for .get() accesses to potentially empty Optional values, analogously to how it handles dereferences to @Nullable values. Calling .get() on an Optional value that hasn't been previously tested with Optional.isPresent(...) (or otherwise tested for non-emptiness in a way NullAway understands) will result in an error.
This works out of the box for java.util.Optional. Additionally, the following option can be used to tell NullAway of other Optional implementations (e.g. Guava's com.google.common.base.Optional).
-XepOpt:NullAway:CheckOptionalEmptinessCustomClasses=...
Optional handling (for both JDK and custom Optional classes) is currently disabled by default, but it is under active development. Feel free to try it out and let us know what might still be missing.
-XepOpt:NullAway:HandleTestAssertionLibraries=...
By default, NullAway does not handle assertions from test libraries. If set to true, NullAway will handle assertions from test libraries, like assertThat(...).isNotNull(), and use that to reason about the possibility of null dereferences in the code that follows these assertions.
-XepOpt:NullAway:CheckContracts=...
NullAway has support for JetBrains @Contract annotations. By default, these annotations are trusted but not checked. If this option is set to true, NullAway will check that @Contract annotations are valid (for the subset of @Contract annotations supported by NullAway).
-XepOpt:NullAway:CustomContractAnnotations=...
By default, NullAway recognizes org.jetbrains.annotations.Contract as a contract annotation. This option allows for specifying an additional list of annotations that should be recognized as providing contracts (with the same contract syntax as org.jetbrains.annotations.Contract).
-XepOpt:NullAway:ExtraFuturesClasses=...
NullAway currently has temporary special support for reasoning about callbacks passed to Guava's Futures and FluentFuture classes; see https://github.com/uber/NullAway/pull/771. This option allows for specifying an additional list of classes that should be recognized as equivalent to those two Guava classes. This special support will likely be removed once NullAway's JSpecify support is more complete.
-XepOpt:NullAway:LegacyAnnotationLocations=...
NullAway 0.12.0 changes the logic for how type-use annotations are interpreted to be consistent with the JSpecify specification. See JSpecify Support for more details. Setting the LegacyAnnotationLocations flag re-enables NullAway's previous logic for interpreting these annotations, to ease migration. We expect to remove this flag in a future NullAway release.
-XepOpt:NullAway:JSpecifyMode=...
Enables experimental support for fuller JSpecify checking. See JSpecify Support for more details.
-XepOpt:NullAway:WarnOnGenericInferenceFailure=...
Within JSpecify mode, this flag enables NullAway warnings when inference fails for a generic method call. This may help diagnose the root cause of certain failures or bugs in NullAway's JSpecify support.
-XepOpt:NullAway:SuppressionNameAliases=...
A list of names to suppress NullAway using a @SuppressWarnings annotation, similar to @SuppressWarnings("NullAway").
This is useful when other warnings are already suppressed in the codebase and NullAway should be suppressed as well, such as with JetBrains' DataFlowIssue inspection.
A few options, marked above, support a restricted regular expression syntax to specify the package names they cover. The main difference between our syntax and standard Java regular expressions, is that the . character is interpreted as a literal dot, not as "any character", as dots are part of the standard package name syntax and treating them literally favors the common case.
It is still possible to cover patterns of package names, such as:
-XepOpt:NullAway:UnannotatedSubPackages=[a-zA-Z0-9.]*.unannotated
(Will consider any code inside any subpackage named unannotated, including subpackages thereof, as unannotated. E.g. a.unanoted, x.y.z.unannotated.z.)
-XepOpt:NullAway:UnannotatedSubPackages=com.myorg.generated_[a-zA-Z0-9]*
(Matches com.myorg.generated_Foo.subpackage, but not com.myorg.source_Foo.subpackage or comxmyorg.generated_Foo.)
In addition to these options, NullAway will look for any classes implementing the com.uber.nullaway.LibraryModels interface, in the annotation processor path, and consider those as plug-in models for third-party unannotated libraries. (We search for such classes using the ServiceLoader facility.) Models defined in such classes will be loaded in addition to the default models for common Java and Android libraries included with the checker itself. For documentation on writing such custom models, refer to the javadoc documentation for com.uber.nullaway.LibraryModels itself. Also see our sample library model for an example; it is pulled in and used by our sample Java module (see the build.gradle file). Note that if you can edit the source code of the library, you might be able to add @Contract annotations instead of writing a library model.
Sometimes, it is useful to suppress some library models on a per-compilation target basis, without changing or adding custom library models classes. In these cases, it is possible to skip all Library Models (included with NullAway and custom) for a specific method, simply by passing it to the following option:
-XepOpt:NullAway:IgnoreLibraryModelsFor=com.example.Foo.bar,com.example.Foo.baz
This takes a list of comma-separated methods, given as their fully-qualified class name plus the method simple name.
Note that, for simplicity of dealing with command-line escaped characters and the like, there is currently no way to give the full signature of the method (i.e. the argument types) when using this option. Thus, methods passed to -XepOpt:NullAway:IgnoreLibraryModelsFor will technically refer to all methods matching the given class and method name.
For configuring Error Prone with Maven, see the docs. It's also good to be familiar with how flags should be passed to Error Prone with Maven; see these docs. Here is an example Maven build configuration (based on the Error Prone example) that pulls in Error Prone and NullAway:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>11</source>
<target>11</target>
<encoding>UTF-8</encoding>
<compilerArgs>
<arg>-XDcompilePolicy=simple</arg>
<arg>-Xplugin:ErrorProne -XepOpt:NullAway:AnnotatedPackages=com.uber</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_core</artifactId>
<version>2.23.0</version>
</path>
<path>
<groupId>com.uber.nullaway</groupId>
<artifactId>nullaway</artifactId>
<version>0.10.15</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>An example (based on this).
WORKSPACE:
maven_jar(
name='jsr305',
artifact='com.google.code.findbugs:jsr305:3.0.2',
)
maven_jar(
name="nullaway",
artifact="com.uber.nullaway:nullaway:0.3.4"
)BUILD:
java_library(
name='x',
srcs=['X.java'],
deps=['@jsr305//jar'],
plugins=['nullaway'],
javacopts=[
'-Xep:NullAway:ERROR',
'-XepOpt:NullAway:AnnotatedPackages=com.example',
],
)
java_plugin(
name='nullaway',
deps=[
'@nullaway//jar'
],
)The first step is to get Error Prone running on your build, as documented here. Then, you need to get the NullAway jar on the annotation processor path for the Javac invocations where Error Prone is running. Finally, you need to pass the appropriate compiler arguments to configure NullAway (at the least, the -XepOpt:NullAway:AnnotatedPackages option).
[Only in version 0.9.9]
-XepOpt:NullAway:AcknowledgeLibraryModelsOfAnnotatedCode=...
This option allows library models to override the annotations on methods within an annotated package. This is useful, e.g., if you want to treat Guava's com.google.common packages as annotated, but also want the default library models of Guava APIs (e.g., of Strings.isNullOrEmpty()) to still apply.
In NullAway 0.9.10+, this option is removed, and library models always override annotations on methods within an annotated packaged (i.e., the option is always on).