关于Code Smell的定义,我就不介绍了,大家可以自己去找。我做这个纯粹是为了响应审稿人的要求,不得不说,现在有些审稿人真是太自以为是,傲慢,固执,得罪不得。
PMD:https://github.com/pmd/pmd 是非常好的Java静态分析工具,例如我们在这里下载:https://github.com/pmd/pmd/releases 其最新的bin文件夹:pmd-bin-6.29.0.zip。解压之后可以顺便把其bin目录加入Path环境变量(我这里用的是Win10)。那么怎么通过命令行来使用其检测Code Smell的功能呢?
在其文档官网浏览一下:https://pmd.github.io/,发现内容很庞杂啊,在这里可以找到其最新版本的Java Rules:https://pmd.github.io/pmd-6.29.0/pmd_rules_java.html
像Best Practice这里:https://pmd.github.io/latest/pmd_rules_java.html#best-practices,就对应了很多Code Smell的检测rules,像:
AbstractClassWithoutAbstractMethod 这个就是抽象类中没有定义抽象方法这个规则。
那我们怎么在命令行里运行呢?这里https://pmd.github.io/latest/pmd_userdocs_installation.html#running-pmd-via-command-line 定义了命令行的基本规则,参考了一下,我尝试写了一个最简单的命令行:
pmd.bat -d Ant-1.7-main -R rules.xml -format csv -language java > Ant-1.7.csv
其中-d指定了分析目录,-R后面跟的是具体的规则,-format定义了生成结果的格式,> Ant-1.7.csv用这个使PMD输出到文本,那么rules.xml怎么写呢?
这里小小吐槽一下,按道理来说:https://pmd.github.io/latest/pmd_userdocs_installation.html#running-pmd-via-command-line 这里介绍了命令行怎么用,应该从这个页面自然链接到怎么写rules.xml啊,只是从create your own ruleset 这个链接里找到了这里:https://pmd.github.io/latest/pmd_userdocs_making_rulesets.html#creating-a-ruleset,不得不说,这个munual还是可以再提高点姿势水平啊。
这里我给出包含两个rules的示例,大家可以在刚才说的这个网页中:https://pmd.github.io/latest/pmd_rules_java.html#best-practices 找到具体的规则的定义方法:
<?xml version="1.0"?><ruleset name="Custom Rules"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 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"><description>My custom rules</description><rule ref="category/java/bestpractices.xml/AbstractClassWithoutAbstractMethod" /><rule ref="category/java/design.xml/AvoidDeeplyNestedIfStmts" /><!-- Your rules will come here --></ruleset>
定义好这些,我们运行上面的命令行,就能得到类似于这样的csv文件了:
"Problem","Package","File","Priority","Line","Description","Rule set","Rule"
"1","org.apache.tools.ant","D:\20201120-CodeSmell\Ant-1.7-main\org\apache\tools\ant\ProjectHelper.java","3","213","Deeply nested if..then statements are hard to read","Design","AvoidDeeplyNestedIfStmts"
具体定义大家一看便知。