在介绍如何自定义规则之前,先介绍一下这几个产品:
虽然开源平台已经帮我们提供众多的Java安全和代码Bug的校验规则(如:P3C、PMD、FindBugs、Sonar Way),但是这些可能仍然无法满足公司对于代码的校验,例如:公司规定不得以老板的姓名作为变量名(类似的需求);因此我们不得不按照老板的规定,来扫描同事们的代码。如何来定义一个自己的Java规范呢,Sonar文档中已有说明:Sonar Doc
按照文档说明,我们应该从头开始开发一个Sonar插件,这显然是非常耗时的,因此我们直接Fork Sonar-PMD 进行修改只需要集成自定义的规则即可。接下来我们就直接进入实操环节,我们以不能将变量定义为password为例。因设计规则需要XPath,请自行学习。
因为我们使用的源码分析器是PMD,因此我们需要使用PMD的规则设计方式,参考文档:PMD 规则设计
PMD的规则设计器可以帮助我们辅助分析AST 可视化的规则设计器
将设计器里的规则copy出来,我们设计为Xpath或使用Java代码分析AST。
我们以不能将变量名称定义为password为例:
//VariableDeclaratorId[@Image = "password"]
public class DontDefinePasswordRule extends AbstractJavaRule{@Overridepublic Object visit(ASTVariableDeclaratorId node, Object data) {if ("password".equalsIgnoreCase(node.getName()) ) {// reports a violation at the position of the node// the "data" parameter is a context object handed to by your rule// the message for the violation is the message defined in the rule declaration XML elementaddViolation(data, node);}return super.visit(node, data);}}
我们可以根据规则的分类,为不同的规则建立不同的规则文件,例如示例的这个配置文件:src\main\resources\rulesets\java\myrule-other.xml
Do not define a variable named password 1
If an abstract class does not provides any methods, it may be acting as a simple data container
that is not meant to be instantiated. In this case, it is probably better to use a private or
protected constructor in order to prevent instantiation than make the class misleadingly abstract. 1
配置文件地址:src\main\resources\org\sonar\plugins\pmd\rules-myrule.xml
MAJOR
配置文件地址:src\main\resources\org\sonar\l10n\pmd.properties
rule.pmd.DontDefinePasswordRule.name=[myrule]Do not define a variable named password.
配置文件地址:src\main\resources\org\sonar\l10n\pmd\rules\pmd-myrule
每个规则一个html文件
Do not define a variable named password. Examples:
private String pwd;
配置文件地址:src\main\resources\com\sonar\sqale\pmd-model.xml
在最后的Myrule PMD中添加clc
pmd DontDefinePasswordRule remediationFunction CONSTANT_ISSUE offset 2 min