静态代码自动扫描p3c的使用

简介: 静态代码自动扫描p3c的使用

当一家公司上了一定的规模,项目越来越多,代码也越来越庞大,然后就是各种五花八门的代码格式、代码规范,通过主程们code review 耗时耗力,很多主程也缺少主观能动性和精力去cover code review这事项,如果有东西能自动化去检查团队成员的编码规范,这样就可以大大的提高代码质量,也可以让核心人员从code review 中解脱出来,本文提到的P3C-PMD就是这种神器。

p3c-pmd是静态代码自动扫描框架,规则是基于pmd规则上修改而来,可以直接参考pmd与jekins集成文档,将规则包换成p3c的包就可以,集成在sonar或gradle或jekins及在线扫描,在流水线上做个定时任务,每天定时扫描,同时它也支持自定义规则,让团队根据自身的需求。

类似的神器还有腾讯的codecc等。

P3C的git仓库如下:

https://github.com/alibaba/p3c/

下面简单说说使用:

1.使用三种方式

1.1. Eclipse plugin

1.2. IDEA plugin

1.3. 命令行扫描

2 规范

规范符合阿里 JAVA代码规范,大的54种大的规则和一系列的小规则,请参考:Java开发手册(黄山版).pdf

规则集

3.如何自定义规则

1.如何新增规范(命令行):

如何提示System.currentTimeMillis() 的禁用?

Summary

Rule name Number of violations
AvoidCallSystemCurrentTimeMillisRule 1

PMD report

Problems found

File Line Problem
java/com/yorha/game/controller/UserController.java 45

核心类:AvoidCallSystemCurrentTimeMillisRule.java

/**
 * don't Use System.currentTimeMillis() to get the current millisecond. user SystemClock.now().
 *
 *
 * @author Allen Jiang
 */
public class AvoidCallSystemCurrentTimeMillisRule extends AbstractXpathRule {
    private static final String XPATH = "//PrimaryPrefix/Name[@Image='System.currentTimeMillis']";
    public AvoidCallSystemCurrentTimeMillisRule() {
        setXPath(XPATH);
    }
    @Override
    public void addViolation(Object data, Node node, String arg) {
        ViolationUtils.addViolationWithPrecisePosition(this, node, data,
                I18nResources.getMessage("java.extend.AvoidCallSystemCurrentTimeMillisRule.violation.msg"));
    }
}

国际化

messages.xml

<entry key="java.extend.AvoidCallSystemCurrentTimeMillisRule.rule.msg">
        <![CDATA[获取当前毫秒数:SystemClock.now(); 而不是System.currentTimeMillis();]]>
    </entry>
    <entry key="java.extend.AvoidCallSystemCurrentTimeMillisRule.rule.desc">
        <![CDATA[
说明:如果想获取更加精确的纳秒级时间值,用SystemClock.nanoTime。在JDK8中,针对统计时间等场景,推荐使用Instant类。
        ]]>
    </entry>
    <entry key="java.extend.AvoidCallSystemCurrentTimeMillisRule.violation.msg">
        <![CDATA[请使用SystemClock.now()代替System.currentTimeMillis()]]>
    </entry>

messages_en.xml

<entry key="java.extend.AvoidCallSystemCurrentTimeMillisRule.rule.msg">
        <![CDATA[Use SystemClock.now() to get the current millisecond. Do not use System.currentTimeMillis(). ]]>
    </entry>
    <entry key="java.extend.AvoidCallSystemCurrentTimeMillisRule.rule.desc">
        <![CDATA[
Note: In order to get a more accurate time, use SystemClock.nanoTime(). In JDK8, use Instant class to deal with situations like time statistics.
        ]]>
    </entry>
    <entry key="java.extend.AvoidCallSystemCurrentTimeMillisRule.violation.msg">
        <![CDATA[please use SystemClock.now() instead of System.currentTimeMillis()]]>
    </entry>

rulesets/ali-extend.xml

<?xml version="1.0"?>
<ruleset name="AlibabaJavaExtends" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
    <description>AlibabaJavaExtends</description>
    <rule name="AvoidCallSystemCurrentTimeMillisRule" language="java"
          message="java.extend.AvoidCallSystemCurrentTimeMillisRule.rule.msg"
          class="com.alibaba.p3c.pmd.lang.java.rule.extend.AvoidCallSystemCurrentTimeMillisRule">
        <description>java.extend.AvoidCallSystemCurrentTimeMillisRule.rule.desc</description>
        <priority>1</priority>
        <example>
            <![CDATA[
    public class TimeMillisDemo {
        public static void main(String args[]) {
            // Positive example:
           long a = SystemClock.now();
            // Negative example:
              long b = System.currentTimeMillis();
            System.out.println(a);
            System.out.println(b);
        }
    }
]]>
        </example>
    </rule>
</ruleset>

4.如何屏蔽规范:

在命令行中,可以根据优先级屏蔽部分规则,根据你需要的加入ruleset白名单黑名单规则

5.如何启动

java -server -jar $PWD/p3c-pmd-2.1.1.jar -d  ../../../proj/yorha-game/src/main -f summaryhtml -cache cache.log -shortnames -R rulesets/java/ali-exception.xml,rulesets/java/ali-oop.xml,rulesets/java/ali-flowcontrol.xml,rulesets/java/ali-naming.xml,rulesets/java/ali-extend.xml -r /home/cnc_build/pmd/report.html  -encoding UTF-8 > p3c.log 2>&1 &

具体使用选项说明如下:

Usage: pmd [options]
  Options:
    -failOnViolation, --failOnViolation
      By default PMD exits with status 4 if violations are found. Disable this
      option with '-failOnViolation false' to exit with 0 instead and just
      write the report.
      Default: true
    -auxclasspath
      Specifies the classpath for libraries used by the source code. This is
      used by the type resolution. Alternatively, a 'file://' URL to a text
      file containing path elements on consecutive lines can be specified.
    -benchmark, -b
      Benchmark mode - output a benchmark report upon completion; default to
      System.err.
      Default: false
    -cache
      Specify the location of the cache file for incremental analysis. This
      should be the full path to the file, including the desired file name
      (not just the parent directory). If the file doesnt exist, it will be
      created on the first run. The file will be overwritten on each run with
      the most up-to-date rule violations.
    -dir, -d
      Root directory for sources.
    -encoding, -e
      Specifies the character set encoding of the source code files PMD is
      reading (i.e., UTF-8).
      Default: UTF-8
    -filelist
      Path to a file containing a list of files to analyze.
    -format, -f
      Report format type.
      Default: text
    -help, -h, -H
      Display help on usage.
    -ignorelist
      Path to a file containing a list of files to ignore.
    -language, -l
      Specify a language PMD should use.
    -minimumpriority, -min
      Rule priority threshold; rules with lower priority than configured here
      won.t be used. Valid values are integers between 1 and 5 (inclusive),
      with 5 being the lowest priority.
      Default: 5
    -no-cache
      Explicitly disable incremental analysis. The '-cache' option is ignored
      if this switch is present in the command line.
      Default: false
    -norulesetcompatibility
      Disable the ruleset compatibility filter. The filter is active by
      default and tries automatically 'fix' old ruleset files with old rule
      names
      Default: false
    -property, -P
      {name}={value}: Define a property for the report format.
      Default: []
    -reportfile, -r
      Sends report output to a file; default to System.out.
  * -rulesets, -R
      Comma separated list of ruleset names to use.
    -shortnames
      Prints shortened filenames in the report.
      Default: false
    -showsuppressed
      Report should show suppressed rule violations.
      Default: false
    -stress, -S
      Performs a stress test.
      Default: false
    -suppressmarker
      Specifies the string that marks a line which PMD should ignore; default
      is NOPMD.
      Default: NOPMD
    -threads, -t
      Sets the number of threads used by PMD.
      Default: 1
    -uri, -u
      Database URI for sources.
    -debug, -verbose, -D, -V
      Debug mode.
      Default: false
    -version, -v
      Specify version of a language PMD should use.

5.静态扫描流水线

拉取最新代码—>每日定时扫描—>生成报表—>发送链接到企业微信群

Summary

Rule name Number of violations
AbstractClassShouldStartWithAbstractNamingRule 20
ClassNamingShouldBeCamelRule 11
AvoidComplexConditionRule 7
AvoidStartWithDollarAndUnderLineNamingRule 1
PojoMustOverrideToStringRule 1
SwitchStatementRule 2
LowerCamelCaseVariableNamingRule 64
EqualsAvoidNullRule 3
AvoidCallSystemCurrentTimeMillisRule 1
ConstantFieldShouldBeUpperCaseRule 13
PackageNamingRule 67
PojoMustUsePrimitiveFieldRule 6
# File Line Problem
1 java/com/yorha/game/controller/IOController.java 19 【IOController】不符合UpperCamelCase命名风格
2 java/com/yorha/game/controller/UserController.java 45 请使用SystemClock.now()代替System.currentTimeMillis()
3 java/com/yorha/game/db/GameTcaplusManager.java 253 变量名【ScenePlayerId】不符合lowerCamelCase命名风格
4 java/com/yorha/game/db/GameTcaplusManager.java 410 变量名【ClanId】不符合lowerCamelCase命名风格
5 java/com/yorha/game/db/GameTcaplusManager.java 424 变量名【ClanId】不符合lowerCamelCase命名风格
6 java/com/yorha/game/db/GameTcaplusManager.java 459 变量名【ClanId】不符合lowerCamelCase命名风格
7 java/com/yorha/game/db/GameTcaplusManager.java 489 方法名【getPlayerEntityDBX】不符合lowerCamelCase命名风格

P3C和CodeCC的比较

名称 P3C CodeCC
便利性 需要自行打包,配置规则和命令行 很方便,直接界面操作使用
界面友好性 只有明细,没有界面 能看到综合信息
默认扫描规则 默认54条规则 默认51条针对JAVA的规则,如要其他规则,还可以从627条备用规则里去选
自定义规则 支持扩展 ,但要学习XPATH的语法 当前版本暂不支持「自定义规则的添加」,相关功能在排期开发中
蓝盾流水线整合 很方便 通过添加插件的方式,不支持私有构建机,可使用Docker公共构建机执行插件
报表明细 只能看到某一行出现了代码问题,但不能定位到责任人是谁 能定位到问题,责任人,以及代码质量的发展和修复趋势,还可以跟进问题的状态及评论
过滤规则 通过去掉rule配置 通过页面勾选

总结

总之,项目越来越大,团队越来越大,代码越来越来多,然后就是各种五花八门的代码格式、代码规范。通过阿里P3C-PMD配合Gitlab做编码规范检查,可以大大提升团队代码质量。

扩展阿里p3c实现自定义代码规范检查

扩展ALIBABA P3C 实现自定义代码规范检查

扩展阿里p3c实现自定义代码规范检查

Java P3C自定义规则

目录
相关文章
|
2月前
|
Arthas 存储 Java
不重启 JVM,如何替换掉已经加载的类
不重启 JVM,如何替换掉已经加载的类
33 0
|
10月前
|
缓存 小程序 API
小程序:浅谈小程序更新机制,发版后多久能全覆盖
小程序:浅谈小程序更新机制,发版后多久能全覆盖
267 0
|
人工智能 JavaScript IDE
自动写代码?别闹了!
这几天,GitHub 上有个很火的插件在抖音刷屏了——Copilot。 这个神器有啥用呢?简单来讲,它就是一款由人工智能打造的编程辅助工具。 我们来看看它有啥用。
316 0
配置静态和动态
介绍: 静态nat 和 动态nat 的配置 静态nat 配置步骤 第一步 配置接口地址 第二步 配置静态地址转换 ip nat inside source static 内部私有地址 转换之后的公网地址 动态nat 配置步骤 第一步 配置接口地址 第二步 配置标准acl 指定需要转换的多个内部主机地址 access-list 编号 permit 网段地址 子网掩码反码 第三步 配置 转换后的公网地址地址池 ip nat pool 地址池名字 起始地址 结束地址 子网掩码 第四步 配置动态地址
122 0
|
存储 JSON Kubernetes
trivy【3】自定义扫描策略
trivy【3】自定义扫描策略
trivy【3】自定义扫描策略
|
缓存
读源码长知识 | 动态扩展类并绑定生命周期的新方式
在阅读viewModelScope源码时,发现了一种新的方式。 协程需隶属于某 CoroutineScope ,以实现structured-concurrency,而 CoroutineScope 应
136 0
【Lua篇】静态代码扫描分析(四)规则检查
通过前面三篇文章已经初步实现了将Lua源代码文件读取解析成语法树,现在就可以通过得到的语法树进行指定规则的代码扫描检查。下图简单列举了一下单个Lua文件内部的语法关系情况(注意并非真正的类图,也没有列举完全部的节点类型)。
432 0
【Lua篇】静态代码扫描分析(四)规则检查
|
安全
【Lua篇】静态代码扫描分析(一)
静态代码分析是一种通过检查代码而不是执行程序来发现源代码中错误的手段。通常可以帮助我们发现常见的编码错误,例如: 语法错误 违反制定的标准编码 未定义的变量 安全性问题 静态代码分析可以通过评估编写的代码来提高代码质量;可以稳定的运行且可以轻松自动化;增加了在源代码中发现漏洞的可能性,从而提高应用安全;由于是针对源码扫描可以在离线的开发环境中完成。但是静态代码分析并不能完全保证编写的代码没有Bug,它也有一些缺点,
855 0
【Lua篇】静态代码扫描分析(一)
|
XML Android开发 数据格式
【PageLayout】非常简单的一键切换加载-空数据-错误页,支持自定义
版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/82594706 项目中我们经常会用到的加载数据,加载完数据后显示内容,如果没有数据显示一个空白页,这是如果网络错误了显示一个网络错误页,自定义一个PageLayout。
1128 0