# PMD Java API

The easiest way to run PMD is to just use a build plugin in your favorite build tool like Apache Ant, Apache Maven or Gradle.

There are also many integrations for IDEs available, see Tools.

If you have your own build tool or want to integrate PMD in a different way, you can call PMD programmatically, as described here.

## Dependencies

You’ll need to add the dependency to the language, you want to analyze. For Java, it will be `net.sourceforge.pmd:pmd-java`. If you use Maven, you can add a new (compile time) dependency like this:

    <dependency>
        <groupId>net.sourceforge.pmd</groupId>
        <artifactId>pmd-java</artifactId>
        <version>${pmdVersion}</version>
    </dependency>

Note: You’ll need to select a specific version. This is done in the example via the property `pmdVersion`.

This will transitively pull in the artifact `pmd-core` which contains the API.

## Command line interface

The easiest way is to call PMD with the same interface as from command line. The main class is `net.sourceforge.pmd.PMD`:

    import net.sourceforge.pmd.PMD;

    public class Example {
        public static void main(String[] args) {
            String[] pmdArgs = {
                "-d", "/home/workspace/src/main/java/code",
                "-R", "rulesets/java/quickstart.xml",
                "-f", "xml",
                "-r", "/home/workspace/pmd-report.xml"
            };
            PMD.main(pmdArgs);
        }
    }

It uses the same options as described in PMD CLI reference.

## Programmatically, variant 1

This is very similar:

    import net.sourceforge.pmd.PMD;
    import net.sourceforge.pmd.PMDConfiguration;

    public class PmdExample {

        public static void main(String[] args) {
            PMDConfiguration configuration = new PMDConfiguration();
            configuration.setInputPaths("/home/workspace/src/main/java/code");
            configuration.addRuleSet("rulesets/java/quickstart.xml");
            configuration.setReportFormat("xml");
            configuration.setReportFile("/home/workspace/pmd-report.xml");

            PMD.runPmd(configuration);
        }
    }

## Programmatically, variant 2

This gives you more control over which files are processed, but is also more complicated. You can also provide your own custom renderers.

1. First we create a `PMDConfiguration` and configure it, first the rules:

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

2. Then we configure, which paths to analyze:

       configuration.setInputPaths("/home/workspace/src/main/java/code");

3. The we configure the default language version for Java. And in order to support type resolution, PMD needs to have access to the compiled classes and dependencies as well. This is called “auxclasspath” and is also configured here.

   Note: you can specify multiple class paths separated by `:` on Unix-systems or `;` under Windows.

       configuration.setDefaultLanguageVersion(LanguageRegistry.findLanguageByTerseName("java").getVersion("11"));
       configuration.prependAuxClasspath("/home/workspace/target/classes:/home/.m2/repository/my/dependency.jar");

4. Then we configure the reporting. Configuring the report file is optional. If not specified, the report will be written to `stdout`.

       configuration.setReportFormat("xml");
       configuration.setReportFile("/home/workspace/pmd-report.xml");

5. Now an optional step: If you want to use additional renderers as in the example, set them up before calling PMD. You can use a built-in renderer, e.g. `XMLRenderer` or a custom renderer implementing `Renderer`. Note, that you must manually initialize the renderer by setting a suitable `Writer`:

       Writer rendererOutput = new StringWriter();
       Renderer renderer = createRenderer(rendererOutput);

       // ...
       private static Renderer createRenderer(Writer writer) {
           XMLRenderer xml = new XMLRenderer("UTF-8");
           xml.setWriter(writer);
           return xml;
       }

6. Finally we can start the PMD analysis. There is the possibility to fine-tune the configuration by adding additional files to analyze or adding additional rulesets or renderers:

       try (PmdAnalysis pmd = PmdAnalysis.create(configuration)) {
           // optional: add more rulesets
           pmd.addRuleSet(pmd.newRuleSetLoader().loadFromResource("custom-ruleset.xml"));
           // optional: add more files
           pmd.files().addFile(Paths.get("src", "main", "more-java", "ExtraSource.java"));
           // optional: add more renderers
           pmd.addRenderer(renderer);

           // or just call PMD
           pmd.performAnalysis();
       }

   The renderer will be automatically flushed and closed at the end of the analysis.

7. Then you can check the rendered output.

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

Here is a complete example:

    import java.io.IOException;
    import java.io.StringWriter;
    import java.io.Writer;
    import java.nio.file.Paths;

    import net.sourceforge.pmd.PMDConfiguration;
    import net.sourceforge.pmd.PmdAnalysis;
    import net.sourceforge.pmd.RulePriority;
    import net.sourceforge.pmd.lang.LanguageRegistry;
    import net.sourceforge.pmd.renderers.Renderer;
    import net.sourceforge.pmd.renderers.XMLRenderer;

    public class PmdExample2 {

        public static void main(String[] args) throws IOException {
            PMDConfiguration configuration = new PMDConfiguration();
            configuration.setMinimumPriority(RulePriority.MEDIUM);
            configuration.addRuleSet("rulesets/java/quickstart.xml");

            configuration.setInputPaths("/home/workspace/src/main/java/code");

            configuration.setDefaultLanguageVersion(LanguageRegistry.findLanguageByTerseName("java").getVersion("11"));
            configuration.prependAuxClasspath("/home/workspace/target/classes");

            configuration.setReportFormat("xml");
            configuration.setReportFile("/home/workspace/pmd-report.xml");

            Writer rendererOutput = new StringWriter();
            Renderer renderer = createRenderer(rendererOutput);

            try (PmdAnalysis pmd = PmdAnalysis.create(configuration)) {
                // optional: add more rulesets
                pmd.addRuleSet(pmd.newRuleSetLoader().loadFromResource("custom-ruleset.xml"));
                // optional: add more files
                pmd.files().addFile(Paths.get("src", "main", "more-java", "ExtraSource.java"));
                // optional: add more renderers
                pmd.addRenderer(renderer);

                // or just call PMD
                pmd.performAnalysis();
            }

            System.out.println("Rendered Report:");
            System.out.println(rendererOutput.toString());
        }

        private static Renderer createRenderer(Writer writer) {
            XMLRenderer xml = new XMLRenderer("UTF-8");
            xml.setWriter(writer);
            return xml;
        }
    }

Tags: userdocs tools