题记:
最近在开发项目中,突然技术经理进行使用sonar
或者findBugs
进行检查代码,通过这些bug与漏洞进行修复,然后根据修复的漏洞进行总结,另外也找网上的sonar修复漏洞的技术进行总结。
由于项目涉及到保密性所有打上马赛克。
一、什么是sonar
Sonar 是一个用于代码质量管理的开放平台。通过插件机制,Sonar 可以集成不同的测试工具,代码分析工具,以及持续集成工具。
与持续集成工具(例如 Hudson/Jenkins
等)不同,Sonar 并不是简单地把不同的代码检查工具结果(例如 FindBugs,PMD 等)直接显示在 Web 页面上,而是通过不同的插件对这些结果进行再加工处理,通过量化的方式度量代码质量的变化,从而可以方便地对不同规模和种类的工程进行代码质量管理。
在对其他工具的支持方面,Sonar 不仅提供了对 IDE 的支持,可以在 Eclipse 和 IntelliJ IDEA 这些工具里联机查看结果;同时 Sonar 还对大量的持续集成工具提供了接口支持,可以很方便地在持续集成中使用 Sonar。、
二、安装部署
其源代码需要使用分布式版本控制软件 Git 进行检出(Check Out
),命令行方式如下:
git clone git://github.com/SonarSource/sonar.git
本文主要介绍 Sonar 的使用方法,只需要到 Sonar 网站下载最近的发行包即可
下载 zip 包后,直接解压到任意目录,由于 Sonar 自带了 Jetty 6 的应用服务器环境,所以不需要额外的安装就可以使用,值得一提的是 Sonar 也支持部署在 Apache Tomcat
应用服务器中。
在 windows 环境中,直接启动 Soanr 的 bin 目录下 windows-x86-64\StartSonar.bat
即可。
然后在浏览器中访问:http://localhost:9000/ 默认账户:admin/admin
在linux
环境 使用命令bin/linux-x86-64/sonar.sh start
启动服务
三、配置使用
参考此博客:https://segmentfault.com/a/1190000009782863
四、错误总结
4.1、
非空判断
logger.info("check category name, tenantId={},ids={}", tenantId, ids.toArray().toString());
解决办法
logger.info("",Arrays.toString( ids.toArray()));
4.2、
list非空判断
List<RoleMenu> relationList = new ArrayList<RoleMenu>(templateList.size());
解决办法
if (GenericValidator.isNullOrBlank(templateList)) {
logger.error("");
}
这是我遇到最多的问题。以下在网上找了一些很好的sonar扫描出来的bug进行总结。
4.3、Close this"FileInputStream" in a "finally" clause.
连接,流,文件等需要在使用后关闭。这些操作都应该放在 finally 代码块里面,防止异常情况发生而没有调用关闭资源的代码。或者是、fileInputStream 有可能为 null,有潜在的空指针异常存在。应该加上非空判断。加上非空判断后就是最标准的 IO 流处理了。
FileInputStream fileInputStream = null;
try {
// do sth
fileInputStream = new FileInputStream("222");
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
fileInputStream.close();
}
解决办法
FileInputStream fileInputStream = null;
try {
// do sth
fileInputStream = new FileInputStream("222");
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if(fileInputStream != null){
fileInputStream.close();
}
}
4.4、
精度错误
Equality tests should not be made with floating point value
if (result == num) //result和num均为double 之间比较会有精度损失
解决办法
BigDecimal data1 = new BigDecimal(totalArea);
BigDecimal data2 = new BigDecimal(s1);
int num = data1.compareTo(data2);
//num =0 相等 >0前者大于后者 ,反之 <0 前者小于后者
4.5、
This class overrides “equals()” and should therefore also override “hashCode()”.
public boolean equals(Object obj){...} //需要添加对应的hashCode方法
解决办法
可以添加一个最简单的hashCode方法
public int hashCode() {return 0;}
4.6、
Synchronize on a new “Object” instead
synchronized ("实例化") {...} //里边必须是对象
解决办法
解决: private Object obj ="实例化";
synchronized (obj ) {...}
4.7、
Close this"FileInputStream" in a “finally” clause.
解决办法
在finally中关闭FileInputStream,主要是关闭方式不对,finally代码块中,应该要对每个stream进行单独关闭,而不能统一写在一个try-catch代码中。
4.8、
A"NullPointerException" could be thrown; “tom” is nullablehere
解决办法
先判断或者先实例化,再访问里面的属性或者成员。
4.9、
Makethis IP “127.0.0.1” address configurable
解决办法
不要把IP地址写在此类中,应该在对应的系统文件或者相应的配置文件中配置
4.10、
Either log or rethrow this exception.
解决办法
把对应的输出写成Logger.error("aaa“);的形式
4.11、
使用字符索引 : String.indexOf(char) is faster than String.indexOf(String).
if(splitArray[i].indexOf("}")!=-1)
解决办法
if(splitArray[i].indexOf('}')!=-1)
4.12、
在进行比较时,字符串文本应该放在左边 : Move the “0” string literal on the left side of this string comparison.
if(enNameArray[1].equals("0")){
enName = enNameArray[2];
}
解决办法
if("0".equals(enNameArray[1])){ }
4.13、
应该使用Collection.isEmpty()判断空集合 : Use isEmpty() to check whether the collection is empty or not.
if(names.size() == 0){ }
解决办法:
if(names.isEmpty()){}
4.14、
类型转换方法Use “Integer.parseInt” for this string-to-int conversion类型转换的方法有很多种方式,
String num = "12.2";
float f = new Float(num).floatValue(); // Noncompliant; creates & discards a Float
解决办法
String num = "12.2";
float f = Float.parseFloat(num);
4.15、
待续
五、结束Sonar
为代码的质量管理提供了一个平台,对传统的代码静态检测如 PMD、FindBugs
等工具进行整合,可以说是目前最强大的代码质量管理工具之一。
1 List<A> list = new ArrayList<为空,不用写A>;
2 try catch 中 catch的exception需记录Exception信息,eg:Logger.error(e.getMessage(),e);
3 return x; return x+3; return (x+3)/2; 不用写成 return (x); return (x+3); return ((x+3)/2);
4 if for while switch 等嵌套循环,复杂度不能超过10,否则代码不易读;
5 判断List 是否为空的写法: list!=null &&list.size()>0 标注红色部分应改为 list.isEmpty();
6 注释的代码尽量删掉,整洁;
7 单线程的方法中用StringBuilder > StringBuffer、StringBuilder单线程中的性能比StringBuffer高;
8 不复用变量或对象 eg:
String str1 = "abc";
String str2 = "efg";
str1 = str1 + str2;
这里需创建新的变量String str3 = str1 +str2;
9 返回空时,需写成 return Collection.emptyXXX; 而不是return null;
10 空的方法包括构造方法,需要文字注释;
11 重写方法时,不要漏掉@Override;
12 变量名不能与类名一样。
参考:https://www.cnblogs.com/Jenny22/p/6495260.html
参考:https://www.sonarqube.org/