DevOps on DevCloud|代码检查服务如何降低Java应用“Billion Dollar Mistake“NPE风险

举报
伦语春秋 发表于 2019/07/18 15:45:36 2019/07/18
【摘要】 在“DevOps能力之屋(Capabilities House of DevOps)”中,华为云DevCloud提出(工程方法+最佳实践+生态)×工具平台=DevOps能力。华为云DevCloud将持续推出“DevOps on DevCloud”系列。本作者与敏而至善在本文中将聚焦阐述如何使用华为云DevCloud代码检查服务来防止Java NPE。

引言:“DevOps能力之屋(Capabilities House of DevOps中,华为云DevCloud提出(工程方法+最佳实践+生态)×工具平台=DevOps能力。华为云DevCloud将持续推出“DevOps on DevCloud”系列,按场景阐述在华为云DevCloud上的实施方法与实践。本作者与敏而至善在本文中将聚焦阐述如何使用华为云DevCloud代码检查服务来防止Java NPENull Pointer Exception)问题。

 

在“如何构建Kotlin开发的Android Apps”一文曾指出空安全(Null SafetyKotin最吸引Java开发者的特性之一, Kotlin类型系统的目标是消除Null reference的危险性。Tony Hoare2019QCon London上将Null reference称为“my billion-dollar mistake”。所谓Null reference是许多编程语言最为常见的陷阱之一,指的是访问Null reference的成员将导致null reference exception。在Java语言中,Null reference通常等同于NullPointerException(即NPE)。

对于Java开发者来讲,或许只有处理过了NPE,才能成为一名真正的Java开发者。NPE通常来讲,会来自于以下场景:

    • 调用了一个空对象的实例方法;

    • 访问或者修改一个空对象的域成员;

    • 当数组是一个空对象时,取它的长度;

    • 对数组中的某些null元素进行范文或者修改;

    • null当做Throwable值抛出

如何防止NPE,简单来讲,主要是两点要素:手段与方法、意识与经验。Java开发者可以参考以下最佳实践来防空:

    • 通过已知字符串常量而不是未知对象来调用equals()equalsIgnoreCase()方法

    • valueOf()toString()返回相同结果的地方优先使用valueOf()

    • 使用null安全的方法与库

    • 避免从方法中返回null,而是返回空的collection或者array

    • 使用注解@NotNull@Nullable

    • 在代码中避免不必要的autoboxingunboxing

    •  遵循Contract并定义合理的缺省值

    • Java 8中使用Optional

    •  双重入参校验

尽管Java开发者能力对于防空是至关重要的,然而人难免会有所失误。为了进一步降低风险,华为云DevCloud建议项目或者产品团队使用代码检查服务来检查是否存在NPE

1      准备工作

1.1    示例工程

Code4Benchmark是采用Java开发的示例工程,希望用于评估代码质量评估工具或者云服务对代码问题的检查能力,例如空指针(Null Pointer)、资源泄露、SQL注入(SQL Injection)等。

对于空指针场景,目前主要是显式解引用、前置判空、后置判空、空返回值等,代码片段如下:

    •  显式解引用: 直接对null对象解引用

void alwaysCauseNPE(){ 
String s = null; System.out.println(s.length()); 
}


    • 前置判空 :对象前面有判空,后面解引用

void forwardMayCauseNPE(String s){
 if (s != null){ 
dummy();
} 
System.out.println(s.length()); 
}


  • 后置判空 :对象后面有判空,前面解引用

void reverseMayCauseNPE(String s){ 
System.out.println(s.length()); 
if (s != null){
dummy(); 
}
}


  • 空返回值 :空返回值直接解引用

   

 void mayCauseNPE(){
        Pointers.A a = Pointers.mayReturnNull(-10);
        a.method();
}
public static A mayReturnNull(int i){
    if (i > 0){
        return new A();
    }
    return null;
}


Code4Benchmark完整代码可以参考https://github.com/supremeGoodness/Code4Benchmark.git

1.2    创建项目及代码库

开发者可以访问华为云DevCloud,登录后在首页新建项目,选择“空白项目”的Scrum或者看板之一,输入项目名称(例如:CodeCheckBenchmark)即可创建项目。

在访问CodeCheckBenchmark项目,并进入“代码”-“代码托管后,可以点击新建”-“导入外部仓库来创建仓库,输入github上的仓库地址(https://github.com/supremeGoodness/Code4Benchmark.git)。后续步骤接受默认值即可创建仓库。

image.png

1 导入外部仓库来新建代码仓库

2      检查代码

通常情况下,使用华为云DevCloud进行代码检查非常简单:新建代码检查任务然后执行此任务即可。当前前提是默认的规则集通用检查规则集满足代码质量的要求。用户可以在任务的“设置”-“规则集中选择系统内置的其它规则集(例如全面检查规则集)或者自定义的规则集。接下来,我们通过自定义规则集的方式来进行NPE问题的检查。

2.1    自定义规则集

在访问CodeCheckBenchmark项目,并进入“代码”-“代码检查后,在规则集页面“新增规则集”,输入规则集名称rs-npe-java、检查语言等,如图2所示。然后在规则集的配置页面,将“Correctness - Nullcheck of value previously dereferenced”、“Null dereference”、“Correctness - Possible null pointer dereference”等规则从未启用规则中选中保存以变为“已启用”规则

image.png

2 新建检查规则集

image.png

3 配置规则集

2.2    创建检查任务并设置规则集

在访问CodeCheckBenchmark项目,并进入“代码”-“代码检查后,在任务页面新建任务,选择代码仓库Code4Benchmark、输入任务名称cc-Code4Benchmark等完成任务创建。如图4所示为创建后的任务概览。

image.png

4 创建后的任务概览

cc-Code4Benchmark任务中,通过设置来配置自定义的规则集rs-npe-java,如图5所示。

image.png

5 为任务选择自定义的规则集

2.3    执行检查任务

cc-Code4Benchmark任务中,可以点击开始检查。在检查完成后,在概览页面查看检查结果,如图6所示。在概览中,我们可以发现检测出4个问题。

image.png

6 任务检查结果概览

3      分析与修改

cc-Code4Benchmark任务中,在概览页点击未解决问题的数量,或者点击代码问题,可以查看问题详情。对于每一个问题,可以根据修改建议进行相关的问题修订。

image.png

7 问题详情与修改建议

 

NPEJava开发中的经典问题,华为云DevCloud代码检查服务提供的规则不止本文提到的3条规则,具体可以在规则中查看。在实际的项目开发中,用户可以直接选择全面检查规则来进行全方位的代码质量检测,以提升代码质量。

W. Edwards Deming曾说过“Inspection is too late. Quality cannot be inspected into a product or servive. It must be built into it.”本质上,软件质量取决于工程师的意识、能力、方法与技能。然而,工程师的意识、能力、方法与技能需要不断提升。因而,华为云DevCloud代码检查服务在软件交付中仍然具有举足轻重的地位,不仅可以及时发现代码质量问题,而且可以强化工程师的预期行为,有助于提升工程师的意识、能力、方法与技能。



华为云DevCloud作为一站式云端DevOps平台,集成华为近30年研发实践和前沿理念,面向开发者提供研发工具服务,让软件开发简单高效。现支持5人以下额度范围内,可以免费使用,并且可以预约免费的产品演示和技术交流,详情查看华为云官网

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。