Class PmdAnalysis

java.lang.Object
net.sourceforge.pmd.PmdAnalysis
All Implemented Interfaces:
AutoCloseable

public final class PmdAnalysis extends Object implements AutoCloseable
Main programmatic API of PMD. This is not a CLI entry point, see module pmd-cli for that.

Usage overview

Create and configure a PMDConfiguration, then use create(PMDConfiguration) to obtain an instance. You can perform additional configuration on the instance, e.g. adding files to process, or additional rulesets and renderers. Then, call performAnalysis() or one of the related terminal methods.

Simple example


   PMDConfiguration config = new PMDConfiguration();
   config.setDefaultLanguageVersion(LanguageRegistry.findLanguageByTerseName("java").getVersion("11"));
   config.addInputPath(Path.of("src/main/java"));
   config.prependClasspath("target/classes");
   config.setMinimumPriority(RulePriority.HIGH);
   config.addRuleSet("rulesets/java/quickstart.xml");
   config.setReportFormat("xml");
   config.setReportFile("target/pmd-report.xml");

   try (PmdAnalysis pmd = PmdAnalysis.create(config)) {
     // note: don't use `config` once a PmdAnalysis has been created.
     // 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);

     pmd.performAnalysis();
   }
 

Rendering reports

If you just want to render a report to a file like with the CLI, you should use a Renderer. You can add a custom one with addRenderer(Renderer). You can add one of the builtin renderers from its ID using PMDConfiguration.setReportFormat(String).

Reports and events

If you want strongly typed access to violations and other analysis events, you can implement and register a GlobalAnalysisListener with addListener(GlobalAnalysisListener). The listener needs to provide a new FileAnalysisListener for each file, which will receive events from the analysis. The listener's lifecycle happens only once the analysis is started (performAnalysis()).

If you want access to all events once the analysis ends instead of processing events as they go, you can obtain a Report instance from performAnalysisAndCollectReport(), or use Report.GlobalReportBuilderListener manually. Keep in mind collecting a report is less memory-efficient than using a listener.

If you want to process events in batches, one per file, you can use Report.ReportBuilderListener. to implement GlobalAnalysisListener.startFileAnalysis(TextFile).

Listeners can be used alongside renderers.

Specifying the Java classpath

Java rules work better if you specify the path to the compiled classes of the analysed sources. See PMDConfiguration.prependAuxClasspath(String).

Customizing message output

The analysis reports messages like meta warnings and errors through a PmdReporter instance. To override how those messages are output, you can set it in AbstractConfiguration.setReporter(PmdReporter). By default, it forwards messages to SLF4J.

  • Method Details

    • create

      public static PmdAnalysis create(PMDConfiguration config)
      Constructs a new instance from a configuration.
      • The files paths (input files, filelist, exclude list, etc) are explored and the files to analyse are collected into the file collector (files()). More can be added programmatically using the file collector.
      • The rulesets given in the configuration are loaded (PMDConfiguration.getRuleSetPaths())
      • A renderer corresponding to the parameters of the configuration is created and added (but not started).
    • files

      public FileCollector files()
      Returns the file collector for the analysed sources.
    • newRuleSetLoader

      public RuleSetLoader newRuleSetLoader()
      Returns a new ruleset loader, which can be used to create new rulesets (add them then with addRuleSet(RuleSet)).
      
       try (PmdAnalysis pmd = create(config)) {
           pmd.addRuleSet(pmd.newRuleSetLoader().loadFromResource("custom-ruleset.xml"));
       }
       
    • addRenderer

      public void addRenderer(Renderer renderer)
      Add a new renderer. The given renderer must not already be started, it will be started by performAnalysis().
      Throws:
      NullPointerException - If the parameter is null
    • addRenderers

      public void addRenderers(Collection<Renderer> renderers)
      Add several renderers at once.
      Throws:
      NullPointerException - If the parameter is null, or any of its items is null.
    • addListener

      public void addListener(GlobalAnalysisListener listener)
      Add a new listener. As per the contract of GlobalAnalysisListener, this object must be ready for interaction. However, nothing will be done with the listener until performAnalysis() is called. The listener will be closed by performAnalysis(), or close(), whichever happens first.
      Throws:
      NullPointerException - If the parameter is null
    • addListeners

      public void addListeners(Collection<? extends GlobalAnalysisListener> listeners)
      Add several listeners at once.
      Throws:
      NullPointerException - If the parameter is null, or any of its items is null.
      See Also:
    • addRuleSet

      public void addRuleSet(RuleSet ruleSet)
      Add a new ruleset.
      Throws:
      NullPointerException - If the parameter is null
    • addRuleSets

      public void addRuleSets(Collection<RuleSet> ruleSets)
      Add several rulesets at once.
      Throws:
      NullPointerException - If the parameter is null, or any of its items is null.
    • getRulesets

      public List<RuleSet> getRulesets()
      Returns an unmodifiable view of the ruleset list. That will be processed.
    • getLanguageProperties

      public LanguagePropertyBundle getLanguageProperties(Language language)
      Returns a mutable bundle of language properties that are associated to the given language (always the same for a given language).
      Parameters:
      language - A language, which must be registered
    • fileNameRenderer

      public ConfigurableFileNameRenderer fileNameRenderer()
    • performAnalysis

      public void performAnalysis()
      Run PMD with the current state of this instance. This will start and finish the registered renderers, and close all registered listeners. All files collected in the file collector are processed. This does not return a report, as the analysis results are consumed by GlobalAnalysisListener instances (of which Renderers are a special case). Note that this does not throw, errors are instead accumulated into a PmdReporter.
    • performAnalysisAndCollectReport

      public Report performAnalysisAndCollectReport()
      Run PMD with the current state of this instance. This will start and finish the registered renderers. All files collected in the file collector are processed. Returns the output report. Note that this does not throw, errors are instead accumulated into a PmdReporter.
    • getReporter

      public PmdReporter getReporter()
    • close

      public void close()
      Specified by:
      close in interface AutoCloseable
    • runAndReturnStats

      public ReportStats runAndReturnStats()