NullAway是 Uber 开源的一款帮助你清除 Java 代码中的 NullPointerException(NPE)的工具,快速且实用。NullAway 类似于 Kotlin 和 Swift 语言中的基于类型的可空性检查,能显着提高开发人员的生产力,同时也满足高要求的安全检查需求。
要使用 NullAway,你必须先在代码(字段,方法参数或返回值为 null)中添加@Nullable注释。给定这些注释,NullAway 执行本地的一系列一致性检查,以确保在代码中取消引用的任何指针不能为空。
NullAway 很快。它被构建为 Error Prone 的一个插件,Error Prone 的运行代码检查作为 Java 编译过程标准的一部分。此编译器的集成允许检查编译器已经完成的工作,如代码解析和类型检查。此外,NullAway 和 Error Prone 可直接集成到我们用于 Android 代码的构建工具 Buck 所支持的快速内存并行构建中。因此,NullAway 可以比在正常构建过程之外运行的工具快得多。
这里是NullAway的Gitbhub地址:https://github.com/uber/NullAway
NullAway的安装教程在其Github网站上有发布: https://github.com/uber/NullAway#installation
然而其介绍的并不全面。以下是在Maven项目中使用NullAway的安装方法,若想在别的项目类型中使用NullAway,请访问上述网站。
安装环境要求:JDK1.8(必须为此版本,高或低都会报错)
将下列配置信息加入到Maven项目的pom.xml文件中。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5</version>
<configuration>
<!--NullAway依赖于errorprone进行构建-->
<compilerId>javac-with-errorprone</compilerId>
<forceJavacCompilerUse>true</forceJavacCompilerUse>
<source>1.8</source>
<target>1.8</target>
<showWarnings>true</showWarnings>
<annotationProcessorPaths>
<!--在注解处理器中配置nullaway-->
<path>
<groupId>com.uber.nullaway</groupId>
<artifactId>nullaway</artifactId>
<version>0.8.0</version>
</path>
<!--同时在注解处理器中配置lombok,配适用项目中的一些注解-->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<!--这里对NullAway的一些参数进行配置-->
<arg>-Xep:NullAway:ERROR</arg>
<arg>-XepOpt:NullAway:AnnotatedPackages=com</arg>
</compilerArgs>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-javac-errorprone</artifactId>
<version>2.8</version>
</dependency>
<!-- override plexus-compiler-javac-errorprone's dependency on
Error Prone with the latest version -->
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_core</artifactId>
<version>2.3.4</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
更改上述配置文件中的参数-XepOpt:NullAway:AnnotatedPackages=com
,将com改为你期望的NullAway检测的package。
注: 若使用的是IDE单独配置的mvn,不可在IDE的Terminal中直接运行
此时运行
mvn clean compile
若要在java文件中使用@Nullable,请引入
import javax.annotation.Nullable;
在Github中也提供了类似的例子进行参考:https://github.com/uber/NullAway#code-example
若Error Prone而非NullAway出现错误告警,屏蔽方法是在<compilerArgs>
加入
-XepExcludedPaths:.*/path/path.*
意为去掉路径包含/path/path
的文件的扫描。详情见:http://errorprone.info/docs/flags**
在这里将会介绍NullAway如何帮你发现和纠正NPE错误。
在NullAway的GitHub网站上提供了一种典型的错误以及纠正方法:https://github.com/uber/NullAway#code-example
在其wiki页面也有各种不同类型错误信息的介绍和纠正方法:https://github.com/uber/NullAway/wiki/Error-Messages
开发人员需要手动加入一些注释,如@Nullable
来进行可能的空指针的纠正。
同时,开发人员也可以通过更改一些配置,来实现在规定范围内等功能的检测。如在上文pom.xml文件中,
<arg>-XepOpt:NullAway:AnnotatedPackages=com</arg>
规定了工具检测的范围为名为com的package。
更多的配置信息及其含义请见:https://github.com/uber/NullAway/wiki/Configuration
在实践中,经常会出现一些被认为非错误的错误信息,这时可以使用NullAway的错误屏蔽手段:https://github.com/uber/NullAway/wiki/Suppressing-Warnings 对其进行有效的屏蔽。
注意:在实践中,曾尝试在maven项目里pom.xml中配置使用”类级别的”如 -XepOpt:NullAway:UnannotatedClasses=…, -XepOpt:NullAway:ExcludedClasses=…的参数,均不生效,请开发人员注意,但“包级别的”配置参数如 -XepOpt:NullAway:AnnotatedPackages=…,-XepOpt:NullAway:UnannotatedSubPackages=… 可正常使用,同时,发现可以通过用 -XepOpt:NullAway:UnannotatedSubPackages=… 代替 -XepOpt:NullAway:UnannotatedClasses来实现对类的屏蔽。
NullAway并不是一个完美的工具,它的缺点在于它不会一次报出所有的项目中可能的错误,而是每一个文件中可能的错误,只有将这些错误以NullAway认可的方式改正或屏蔽,它才会进行之后的检测工作。NullAway目前并不具备一些对Spring注解的理解功能,这导致它在处理一些注解,尤其是Java变量初始化的注入依赖时(因为此时NullAway会认为变量只声明而未初始化,是null),会产生大量报错信息。除次之外,NullAway要求变量必须初始化。这些都可以使用并选择步骤二中提到的屏蔽方法进行合理的屏蔽。
若想了解更多,请见NullAway的wiki页面:https://github.com/uber/NullAway/wiki
此工具发现空指针问题的能力非常强大,但属于人工辅助工具,需要耗费一些时间为工具打一些标识,推荐产品使用。