PMD【 Java 代码检查工具】入门使用教程(超详细)

PMD【 Java 代码检查工具】入门使用教程(超详细)PMD Java 代码检查工具 介绍使用方式 1 使用插件的方式 2 maven 项目引入依赖的方式 3 pmd 命令行的方式 4 JavaAPI 的方式 项目结构测试代码 pmdArgs 方式 PMDConfigura 方式 Programmatic 拓展 分析结果图形界面检测自定义规则介绍 nbsp nbsp nbsp nbsp nbsp nbsp PMD 是一个静态源代码分析器 它发现了常见的编程缺陷 如未使用的变量 空捕获块 不必要的对象创建等等 官网 点这里官方文档 点这里使用方

介绍

      PMD是一个静态源代码分析器。它发现了常见的编程缺陷,如未使用的变量、空捕获块、不必要的对象创建等等。

官网:点这里
官方文档:点这里

使用方式

1、使用插件的方式

下载:File -> Settings -> Plugins -> Marketplace 搜索 “PMDPlugin” ,下载插件。

使用方法:在代码编辑框或Project 窗口的文件夹、包、文件右键,选择“Run PMD”->“Pre Defined”->“All”,对指定的文件夹、包、文件进行分析,分析结果在控制台输出。

2、maven项目引入依赖的方式

pom.xml:

 
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0 
     modelVersion> <groupId>com.keafmd 
      groupId> <artifactId>pdm-test01 
       artifactId> <version>1.0-SNAPSHOT 
        version>  
         
        <reporting> <plugins> <plugin> <groupId>org.apache.maven.plugins 
         groupId> <artifactId>maven-pmd-plugin 
          artifactId> <version>3.14.0 
           version>  
            plugin>  
             plugins>  
              reporting>  
               project> 

mvn 命令执行

在项目目录打开cmd窗口,输入以下命令:

mvn pmd:pmd 

在这里插入图片描述
分析结果为pmd.html文件,在项目的target下的site目录下:

在这里插入图片描述

在这里插入图片描述
分析结果显示内容:

在这里插入图片描述

3、pmd 命令行的方式

pmd -d 源代码路径 -f xml(结果输出格式) -r 结果保存所在目录及名称 -R rulesets/java/unusedcode.xml 

例子:

在这里插入图片描述
结果存放在制定文件目录下,格式也为命令语句指定的:

在这里插入图片描述

检测结果内容:
在这里插入图片描述

4、Java API的方式 *

官方文档

需要先引入maven依赖

项目结构

在这里插入图片描述

测试代码

Test01:

package com.keafmd.test01; / * Keafmd * * @ClassName: Test01 * @Description: 测试1 * @author: 牛哄哄的柯南 * @Date: 2021-03-15 15:29 * @Blog: https://keafmd.blog.csdn.net/ */ public class Test01 { 
    public static void main(String[] args) { 
    int a =100; int b=29; String s ="abc"; System.out.println("hello!"); } } 

Test02:

package com.keafmd.test02; / * Keafmd * * @ClassName: Test02 * @Description: * @author: 牛哄哄的柯南 * @Date: 2021-03-15 15:30 * @Blog: https://keafmd.blog.csdn.net/ */ public class Test02 { 
    public static void main(String[] args) { 
    boolean flag=true; while(flag){ 
    flag=false; } System.out.println("123"); int a =100; int b=29; String s ="abc"; System.out.println("hello!"); } } 

pmdArgs方式

命令行接口的方式
最简单的方法是使用与命令行相同的接口调用PMD

Example :

package com.keafmd; import net.sourceforge.pmd.PMD; / * Keafmd * * @ClassName: Example * @Description: * @author: 牛哄哄的柯南 * @Date: 2021-03-15 15:51 * @Blog: https://keafmd.blog.csdn.net/ */ public class Example { 
    public static void main(String[] args) { 
    String[] pmdArgs = { 
    "-d", "D:/javaworkspace/pdm-test02/src", "-R", "rulesets/java/quickstart.xml", "-f", "xml", "-r", "D:/pmdreport/pmd-report.xml" }; PMD.main(pmdArgs); } } 

PMDConfiguration方式

PmdExample:

package com.keafmd; import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.PMDConfiguration; / * Keafmd * * @ClassName: PmdExample * @Description: * @author: 牛哄哄的柯南 * @Date: 2021-03-15 15:57 * @Blog: https://keafmd.blog.csdn.net/ */ public class PmdExample { 
    public static void main(String[] args) { 
    /*String fileName ; // 重新生成文件名(根据具体情况生成对应文件名) fileName = UUID.randomUUID()+"_"+"pmd-report.html"; PMDConfiguration configuration = new PMDConfiguration(); configuration.setInputPaths("D:/file"); configuration.setRuleSets("rulesets/java/quickstart.xml"); configuration.setReportFormat("html"); configuration.setReportFile("D:/pmdreport/"+fileName); PMD.doPMD(configuration);*/ PMDConfiguration configuration = new PMDConfiguration(); configuration.setInputPaths("D:/javaworkspace/pdm-test/src"); configuration.setRuleSets("rulesets/java/quickstart.xml"); configuration.setReportFormat("html"); configuration.setReportFile("D:/pmdreport/pmd-report.html"); PMD.doPMD(configuration); } } 

Programmatically(拓展)

这使您能够更好地控制处理哪些文件,但也会更加复杂。您还可以提供自己的侦听器和呈现器。

1. 首先,我们创建一个PMDConfiguration。目前,这是指定规则集的唯一方法:

PMDConfiguration configuration = new PMDConfiguration(); configuration.setMinimumPriority(RulePriority.MEDIUM); configuration.setRuleSets("rulesets/java/quickstart.xml"); 

2. 为了支持类型解析,PMD还需要访问已编译的类和依赖项。这被称为“生长素路径”,并且在这里也进行了配置。注意:您可以指定由:关于Unix系统或;在Windows下。

configuration.prependClasspath("/home/workspace/target/classes:/home/.m2/repository/my/dependency.jar"); 

3. 那我们需要一个规则工厂。这是使用配置创建的,同时考虑到最低优先级:

RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.createFactory(configuration); 

4. PMD操作于DataSource。您可以收集自己的列表FileDataSource.

List<DataSource> files = Arrays.asList(new FileDataSource(new File("/path/to/src/MyClass.java"))); 

5. 对于报告,您可以使用内置渲染器。XMLRenderer。注意,必须通过设置适当的Writer打电话start()。在pmd运行之后,您需要调用end()flush()。那么你的作者应该收到所有的输出。

StringWriter rendererOutput = new StringWriter(); Renderer xmlRenderer = new XMLRenderer("UTF-8"); xmlRenderer.setWriter(rendererOutput); xmlRenderer.start(); 

6. 创建一个RuleContext。这是上下文实例,在规则实现中是可用的。注意:当在多线程模式下运行时(这是默认的),规则上下文实例将被克隆到每个线程。

RuleContext ctx = new RuleContext(); 

7. 可以选择注册报表侦听器。这样你就可以对发现的违规行为立即做出反应。您也可以使用这样的侦听器来实现您自己的呈现器。侦听器必须实现接口。ThreadSafeReportListener并且可以通过ctx.getReport().addListener(...).

ctx.getReport().addListener(new ThreadSafeReportListener() { 
    public void ruleViolationAdded(RuleViolation ruleViolation) { 
    } public void metricAdded(Metric metric) { 
    } 

8. 现在,所有的准备工作都完成了,PMD可以执行了。这是通过调用PMD.processFiles(...)。此方法调用接受配置、规则集工厂、要处理的文件、规则上下文和呈现器列表。如果不想使用任何渲染器,请提供一个空列表。注意:需要显式关闭辅助路径。否则,类或JAR文件可能会保持打开状态,并且文件资源会泄漏。

try { 
    PMD.processFiles(configuration, ruleSetFactory, files, ctx, Collections.singletonList(renderer)); } finally { 
    ClassLoader auxiliaryClassLoader = configuration.getClassLoader(); if (auxiliaryClassLoader instanceof ClasspathClassLoader) { 
    ((ClasspathClassLoader) auxiliaryClassLoader).close(); } } 

9. 呼叫后,您需要完成渲染器end()flush()。然后,您可以检查呈现的输出。

renderer.end(); renderer.flush(); System.out.println("Rendered Report:"); System.out.println(rendererOutput.toString()); 

下面是一个完整的例子:

import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.PathMatcher; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Collections; import java.util.List; import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.PMDConfiguration; import net.sourceforge.pmd.RuleContext; import net.sourceforge.pmd.RulePriority; import net.sourceforge.pmd.RuleSetFactory; import net.sourceforge.pmd.RuleViolation; import net.sourceforge.pmd.RulesetsFactoryUtils; import net.sourceforge.pmd.ThreadSafeReportListener; import net.sourceforge.pmd.renderers.Renderer; import net.sourceforge.pmd.renderers.XMLRenderer; import net.sourceforge.pmd.stat.Metric; import net.sourceforge.pmd.util.ClasspathClassLoader; import net.sourceforge.pmd.util.datasource.DataSource; import net.sourceforge.pmd.util.datasource.FileDataSource; public class PmdExample2 { 
    public static void main(String[] args) throws IOException { 
    PMDConfiguration configuration = new PMDConfiguration(); configuration.setMinimumPriority(RulePriority.MEDIUM); configuration.setRuleSets("rulesets/java/quickstart.xml"); configuration.prependClasspath("/home/workspace/target/classes"); RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.createFactory(configuration); List<DataSource> files = determineFiles("/home/workspace/src/main/java/code"); Writer rendererOutput = new StringWriter(); Renderer renderer = createRenderer(rendererOutput); renderer.start(); RuleContext ctx = new RuleContext(); ctx.getReport().addListener(createReportListener()); // alternative way to collect violations try { 
    PMD.processFiles(configuration, ruleSetFactory, files, ctx, Collections.singletonList(renderer)); } finally { 
    ClassLoader auxiliaryClassLoader = configuration.getClassLoader(); if (auxiliaryClassLoader instanceof ClasspathClassLoader) { 
    ((ClasspathClassLoader) auxiliaryClassLoader).close(); } } renderer.end(); renderer.flush(); System.out.println("Rendered Report:"); System.out.println(rendererOutput.toString()); } private static ThreadSafeReportListener createReportListener() { 
    return new ThreadSafeReportListener() { 
    @Override public void ruleViolationAdded(RuleViolation ruleViolation) { 
    System.out.printf("%-20s:%d %s%n", ruleViolation.getFilename(), ruleViolation.getBeginLine(), ruleViolation.getDescription()); } @Override public void metricAdded(Metric metric) { 
    // ignored } }; } private static Renderer createRenderer(Writer writer) { 
    XMLRenderer xml = new XMLRenderer("UTF-8"); xml.setWriter(writer); return xml; } private static List<DataSource> determineFiles(String basePath) throws IOException { 
    Path dirPath = FileSystems.getDefault().getPath(basePath); PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.java"); List<DataSource> files = new ArrayList<>(); Files.walkFileTree(dirPath, new SimpleFileVisitor<Path>() { 
    @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException { 
    if (matcher.matches(path.getFileName())) { 
    System.out.printf("Using %s%n", path); files.add(new FileDataSource(path.toFile())); } else { 
    System.out.printf("Ignoring %s%n", path); } return super.visitFile(path, attrs); } }); System.out.printf("Analyzing %d files in %s%n", files.size(), basePath); return files; } } 

分析结果

分析结果会根据指定格式输出在指定文件目录下。

图形界面

检测

D:\MyFile\Tool\pmd-bin-6.32.0\bin 目录下打开cmd窗口输入:

cpdgui.bat 

在这里插入图片描述

自定义规则

在这里插入图片描述
D:\MyFile\Tool\pmd-bin-6.32.0\bin 目录下打开cmd窗口输入:

designer.bat 

在这里插入图片描述

自定义规则:不能有变量为keafmd的String类型的变量

String keafmd; //这样就是不合法的。

Source:

public class KeepingItSerious { 
    Delegator keafmd; // FieldDeclaration public void method() { 
    String keafmd; // LocalVariableDeclaration } } 

导出的自定义规则:

<rule name="myrule" language="java" message="不能有变量为keafmd的String类型的变量" class="net.sourceforge.pmd.lang.rule.XPathRule"> <description> 自定义规则  
     description> <priority>3 
      priority> <properties> <property name="version" value="2.0"/> <property name="xpath"> <value>  //VariableDeclaratorId[@Image = "keafmd" and ../../Type[@TypeImage = "String"]]   
       value>  
        property>  
         properties>  
          rule> 

以上就是PMD【 Java 代码检查工具】入门使用教程(超详细)的全部内容。

看完如果对你有帮助,感谢点赞支持!
如果你是电脑端的话,看到右下角的 “一键三连” 了吗,没错点它[哈哈]


在这里插入图片描述

加油!

共同努力!

Keafmd

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/200939.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午10:17
下一篇 2026年3月20日 上午10:17


相关推荐

  • poe交换机百度百科_交换机带poe什么意思

    poe交换机百度百科_交换机带poe什么意思文章目录前言一、POE交换机与普通交换机的区别二、POE系统的组成三、POE交换机输出电压和功率四、POE系统的四种连接方法五、POE交换机供电距离六、提示1.网线2.不选非标POE3.不用假POE终端设备前言POE(PowerOverEthernet)指的是在现有的以太网Cat.5布线基础架构不作任何改动的情况下,在为一些基于IP的终端(如IP电话机、无线局域网接入点AP、网络摄像机等)传输数据信号的同时,还能为此类设备提供直流电的技术,就是支持以太网供电的交换机。提示:以下是本篇文章正

    2022年10月4日
    7
  • yum卸载软件

    yum卸载软件yum可以安装软件,也可以卸载软件yum安装软件的命令为:yuminstallfileNameyum卸载软件的命令:sudoyumremovedocker\docker-client\docker-client-latest\docker-common…

    2022年5月6日
    1.2K
  • 图书管理系统用例图

    图书管理系统用例图转载于 https www cnblogs com lippman p 6783544 html

    2026年3月19日
    2
  • submit text3 2021 激活码(最新序列号破解)

    submit text3 2021 激活码(最新序列号破解),https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月20日
    45
  • 提升效率解放双手-使用n8n构建自动化工具

    提升效率解放双手-使用n8n构建自动化工具

    2026年3月15日
    3
  • 全网最详细完备的class类文件结构解析

    全网最详细完备的class类文件结构解析写在前面本文隶属于专栏《100个问题搞定Java虚拟机》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!本专栏目录结构和文献引用请见100个问题搞定Java虚拟机解答Class文件是一组以8位字节为基础单位的二进制流,不同的数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有任何空隙存在。这些数据项目由无符号数和表来存储数据,按照顺序依次是:1.魔数和Class文件的版本2.常量池3.访问标志4.类索引、父类索引与接口索引集合5.字段表

    2022年5月6日
    60

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号