热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

Java代码检查工具之PMD入门使用详细教程

这篇文章主要介绍了Java代码检查工具之PMD入门使用详细教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

介绍

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

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

使用方式

1、使用插件的方式

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

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

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

pom.xml:

<&#63;xml version="1.0" encoding="UTF-8"&#63;>

 4.0.0

 com.keafmd
 pdm-test01
 1.0-SNAPSHOT

 

 
 
 
 
 org.apache.maven.plugins
 maven-pmd-plugin
 3.14.0
 
 
 
 

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) {
 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 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 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 determineFiles(String basePath) throws IOException {
 Path dirPath = FileSystems.getDefault().getPath(basePath);
 PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.java");

 List files = new ArrayList<>();

 Files.walkFileTree(dirPath, new SimpleFileVisitor() {
 @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
 }

}

导出的自定义规则:


 
	自定义规则
 
 3
 
 
 
 

 
 
 

到此这篇关于Java 代码检查工具之PMD入门使用详细教程的文章就介绍到这了,更多相关Java 代码检查工具PMD内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
    本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
author-avatar
颓废胖胖2502908443
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有