Overview of the built-in report formats for PMD
Table of Contents

Overview

PMD can report the found rule violations in various formats. Some formats can be customized further via properties. Violations might also be suppressed and there might be processing errors or configuration errors. Not all report formats display all information.

The header of the sections below are used to select the format on the command line, as arguments to the --format option. When a format accepts properties, those can be specified with the --property / -P option on the command-line.

sarif

“SARIF, the Static Analysis Results Interchange Format, is a standard, JSON-based format for the output of static analysis tools. It has been approved as an OASIS standard” - https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html.

SARIF schema can be found here: https://github.com/oasis-tcs/sarif-spec/tree/main/sarif-2.1/schema. In the generated report, we refer to the schema on schemastore.org/json: https://json.schemastore.org/sarif-2.1.0.json.

PMD holds an initial implementation version of SARIF rendering. This means SARIF allows for more complexity and the current implementation can be extended.

Example

codeclimate

Renderer for Code Climate JSON format.

This format is used when running PMD within Code Climate. The renderer will stream JSON objects, each object is a own issue (a PMD rule violation). Each issue is separated by the null character (\0).

The format is specified here: https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md.

The code climate format doesn’t support suppressed violations. It also doesn’t report any errors. But it contains the full rule details for each reported rule violation.

Example:

{"type":"issue","check_name":"GuardLogStatement","description":"Logger calls should be surrounded by log level guards.","content":{"body":"## GuardLogStatement\n\nSince: PMD 5.1.0\n\nPriority: Medium High\n\n[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\n\n[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\n\nWhenever using a log level, one should check if the loglevel is actually enabled, or otherwise skip the associate String creation and manipulation.\n\n### Example:\n\n```java\n\n\n // Add this for performance\n if (log.isDebugEnabled() { ...\n log.debug('log something' + ' and ' + 'concat strings');\n\n \n``` \n\n### [PMD properties](https://pmd.github.io/pmd-6.22.0/pmd_userdocs_configuring_rules.html#rule-properties)\n\nName | Value | Description\n--- | --- | ---\nviolationSuppressRegex | | Suppress violations with messages matching a regular expression\nviolationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\nlogLevels | trace,debug,info,warn,error,log,finest,finer,fine,info,warning,severe | LogLevels to guard\nguardsMethods | isTraceEnabled,isDebugEnabled,isInfoEnabled,isWarnEnabled,isErrorEnabled,isLoggable | Method use to guard the log statement\n"},"categories":["Style"],"location":{"path":"/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java","lines":{"begin":124,"end":125}},"severity":"normal","remediation_points":50000}
{"type":"issue","check_name":"ForLoopCanBeForeach","description":"This for loop can be replaced by a foreach loop","content":{"body":"## ForLoopCanBeForeach\n\nSince: PMD 6.0.0\n\nPriority: Medium\n\n[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\n\n[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\n\nReports loops that can be safely replaced with the foreach syntax. The rule considers loops over lists, arrays and iterators. A loop is safe to replace if it only uses the index variable to access an element of the list or array, only has one update statement, and loops through *every* element of the list or array left to right.\n\n### Example:\n\n```java\n\n\npublic class MyClass {\n void loop(List<String> l) {\n for (int i = 0; i < l.size(); i++) { // pre Java 1.5\n System.out.println(l.get(i));\n }\n\n for (String s : l) { // post Java 1.5\n System.out.println(s);\n }\n }\n}\n\n \n``` \n\n### [PMD properties](https://pmd.github.io/pmd-6.22.0/pmd_userdocs_configuring_rules.html#rule-properties)\n\nName | Value | Description\n--- | --- | ---\nviolationSuppressRegex | | Suppress violations with messages matching a regular expression\nviolationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\n"},"categories":["Style"],"location":{"path":"/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java","lines":{"begin":58,"end":62}},"severity":"normal","remediation_points":50000}

csv

Comma-separated values tabular format.

This format only renders rule violations. Suppressed violations or errors are ignored.

Example:

"Problem","Package","File","Priority","Line","Description","Rule set","Rule"
"1","net.sourceforge.pmd","/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java","2","124","Logger calls should be surrounded by log level guards.","Best Practices","GuardLogStatement"
"1","net.sourceforge.pmd.benchmark","/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java","3","58","This for loop can be replaced by a foreach loop","Best Practices","ForLoopCanBeForeach"

This format can be configured to display only certain columns. In order to not show the problem counter and package columns, use these CLI parameters additionally: -property problem=false -property package=false

Properties:

  • problem: Include problem column. Default: true.
  • package: Include package column. Default: true.
  • file: Include file column. Default: true.
  • priority: Include priority column. Default: true.
  • line: Include line column. Default: true.
  • desc: Include description column. Default: true.
  • ruleSet: Include Rule set column. Default: true.
  • rule: Include Rule column. Default: true.

emacs

GNU Emacs integration.

Example:

/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java:124: Logger calls should be surrounded by log level guards.
/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java:58: This for loop can be replaced by a foreach loop

html

HTML format.

This renderer provides two properties to render a link to the source where the violations have been found. The following example has been created with -property linkPrefix=https://github.com/pmd/pmd/blob/main/ -property linePrefix=L -shortnames -d pmd. If “linkPrefix” is not set, then “linePrefix” has no effect anyway: just the filename will be rendered, with no html link. Otherwise if “linePrefix” is not set, then the link will not contain a line number.

When using Maven JXR Plugin to generate a html view of the project’s sources, then the property “htmlExtension” needs to be set to “true”. This will then replace the normal source file extensions (e.g. “.java”) with “.html”, so that the generated html pages are referenced.

Example

Properties:

  • linePrefix: Prefix for line number anchor in the source file.
  • linkPrefix: Path to HTML source.
  • htmlExtension: Replace file extension with .html for the links (default: false)

ideaj

IntelliJ IDEA integration.

It has two ways of calling:

  1. For a single file: then all three properties need to be provided

pmd check -d src/Foo.java -R rulesets/java/quickstart.xml -f ideaj -P fileName=src/Foo.java -P sourcePath=/home/pmd/src -P classAndMethodName=Foo

  1. For a directory: then the fileName property can be omitted

pmd check -d src -R rulesets/java/quickstart.xml -f ideaj -P sourcePath=/home/pmd/src -P classAndMethodName=.method

Example:

Logger calls should be surrounded by log level guards.
 at Foo(:124)
This for loop can be replaced by a foreach loop
 at Foo(:58)

Properties:

  • classAndMethodName: Class and method name, pass .method when processing a directory.
  • sourcePath:
  • fileName:

json

JSON format.

This prints a single JSON object containing some header information, and then the violations grouped by file. The root object fields are

  • formatVersion: an integer which will be incremented if we change the serialization format
  • pmdVersion: the version of PMD that produced the report
  • timestamp: explicit
  • files: an array of objects (see the example)

Example

summaryhtml

Summary HTML format.

This is the html renderer but with an extra section, the summarizes the violations per rule.

Example

Properties:

  • linePrefix: Prefix for line number anchor in the source file.
  • linkPrefix: Path to HTML source.
  • htmlExtension: Replace file extension with .html for the links (default: false)

text (default)

This is the default format.

This format outputs one line per violation. At the end, processing errors, suppressed violations and configuration errors are reported.

Example:

/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java:124:    GuardLogStatement:    Logger calls should be surrounded by log level guards.
/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java:58:    ForLoopCanBeForeach:   This for loop can be replaced by a foreach loop
/home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java    -   PMDException: Error while parsing /home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
CloseResource rule violation suppressed by Annotation in /home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java
LoosePackageCoupling    -   No packages or classes specified

textcolor

Text format, with color support (requires ANSI console support, e.g. xterm, rxvt, etc.).

Example:

* file: ./pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java
    src:  RuleContext.java:124:125
    rule: GuardLogStatement
    msg:  Logger calls should be surrounded by log level guards.
    code: LOG.warning("The method RuleContext::setSourceCodeFilename(String) has been deprecated and will be removed."

* file: ./pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java
    src:  Benchmarker.java:58:62
    rule: ForLoopCanBeForeach
    msg:  This for loop can be replaced by a foreach loop
    code: for (int i = 0; i < args.length; i++) {



Summary:

net.sourceforge.pmd.RuleContext : 1
net.sourceforge.pmd.benchmark.Benchmarker : 1
* file: ./pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
    err:  PMDException: Error while parsing /home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
net.sourceforge.pmd.PMDException: Error while parsing /home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:110)
    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:89)
    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:51)
    at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:78)
    at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:24)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
    at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: net.sourceforge.pmd.lang.java.ast.ParseException: Encountered " "-" "- "" at line 6, column 30.
Was expecting one of:
    "extends" ...
    "implements" ...
    "{" ...
    "<" ...
    
    at net.sourceforge.pmd.lang.java.ast.JavaParser.generateParseException(JavaParser.java:12713)
    at net.sourceforge.pmd.lang.java.ast.JavaParser.jj_consume_token(JavaParser.java:12597)
    at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceBody(JavaParser.java:1554)
    at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceDeclaration(JavaParser.java:732)
    at net.sourceforge.pmd.lang.java.ast.JavaParser.TypeDeclaration(JavaParser.java:639)
    at net.sourceforge.pmd.lang.java.ast.JavaParser.CompilationUnit(JavaParser.java:373)
    at net.sourceforge.pmd.lang.java.AbstractJavaParser.parse(AbstractJavaParser.java:62)
    at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:121)
    at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:185)
    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:107)
    ... 10 more


* rule: LoosePackageCoupling
    err:  No packages or classes specified

* errors:   2
* warnings: 2

textpad

TextPad integration.

Example:

/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java(124,  GuardLogStatement):  Logger calls should be surrounded by log level guards.
/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java(58,  ForLoopCanBeForeach):  This for loop can be replaced by a foreach loop

vbhtml

Vladimir Bossicard HTML format.

xml

XML format.

This format is a XML document, that can be validated by a XSD schema. The schema is report_2_0_0.xsd.

Example:

<?xml version="1.0" encoding="UTF-8"?>
<pmd xmlns="http://pmd.sourceforge.net/report/2.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://pmd.sourceforge.net/report/2.0.0 https://pmd.github.io/schema/report_2_0_0.xsd"
    version="6.22.0" timestamp="2020-04-11T19:17:03.207">
<file name="/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java">
<violation beginline="124" endline="125" begincolumn="9" endcolumn="111" rule="GuardLogStatement" ruleset="Best Practices" package="net.sourceforge.pmd" class="RuleContext" method="setSourceCodeFilename" externalInfoUrl="https://pmd.github.io/pmd-6.22.0/pmd_rules_java_bestpractices.html#guardlogstatement" priority="2">
Logger calls should be surrounded by log level guards.
</violation>
</file>
<file name="/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java">
<violation beginline="58" endline="62" begincolumn="9" endcolumn="9" rule="ForLoopCanBeForeach" ruleset="Best Practices" package="net.sourceforge.pmd.benchmark" class="Benchmarker" method="findBooleanSwitch" externalInfoUrl="https://pmd.github.io/pmd-6.22.0/pmd_rules_java_bestpractices.html#forloopcanbeforeach" priority="3">
This for loop can be replaced by a foreach loop
</violation>
</file>
<error filename="/home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java" msg="PMDException: Error while parsing /home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java">
<![CDATA[net.sourceforge.pmd.PMDException: Error while parsing /home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:110)
    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:89)
    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:51)
    at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:78)
    at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:24)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
    at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: net.sourceforge.pmd.lang.java.ast.ParseException: Encountered " "-" "- "" at line 6, column 30.
Was expecting one of:
    "extends" ...
    "implements" ...
    "{" ...
    "<" ...
    
    at net.sourceforge.pmd.lang.java.ast.JavaParser.generateParseException(JavaParser.java:12713)
    at net.sourceforge.pmd.lang.java.ast.JavaParser.jj_consume_token(JavaParser.java:12597)
    at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceBody(JavaParser.java:1554)
    at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceDeclaration(JavaParser.java:732)
    at net.sourceforge.pmd.lang.java.ast.JavaParser.TypeDeclaration(JavaParser.java:639)
    at net.sourceforge.pmd.lang.java.ast.JavaParser.CompilationUnit(JavaParser.java:373)
    at net.sourceforge.pmd.lang.java.AbstractJavaParser.parse(AbstractJavaParser.java:62)
    at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:121)
    at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:185)
    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:107)
    ... 10 more
]]>
</error>
<suppressedviolation filename="/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java" suppressiontype="@suppresswarnings" msg="Ensure that resources like this OutputStreamWriter object are closed after use" usermsg=""/>
<configerror rule="LoosePackageCoupling" msg="No packages or classes specified"/>
</pmd>

Properties:

  • encoding: XML encoding format, defaults to UTF-8.

xslt

XML with a XSL transformation applied.

PMD provides one built-in stylesheet, that is used by default, if no other stylesheet with the property “xsltFilename” is specified. It is called pmd-nicerhtml.xsl and can be used for customization.

There are many other stylesheets available online: https://github.com/pmd/pmd/tree/main/pmd-core/etc/xslt.

Examples:

Properties:

  • encoding: XML encoding format, defaults to UTF-8.
  • xsltFilename: The XSLT file name.

yahtml

Yet Another HTML format.

This renderer creates an html file per analyzed source file, hence you need to specify a output directory. The output directory must exist. If not specified, the html files are created in the current directory.

Example

Properties:

  • outputDir: Output directory.
Tags: userdocs