PMD Core - The foundational library module providing essential infrastructure for PMD static code analysis including AST handling, rule execution, configuration management, and reporting mechanisms.
npx @tessl/cli install tessl/maven-net-sourceforge-pmd--pmd-core@7.13.0PMD Core is the foundational library module of PMD, providing essential infrastructure for static code analysis across multiple programming languages. It offers a comprehensive framework for parsing source code into Abstract Syntax Trees (ASTs), executing configurable rules, managing language modules, collecting violations, and rendering reports in various formats.
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-core</artifactId>
<version>7.13.0</version>
</dependency>import net.sourceforge.pmd.PMDConfiguration;
import net.sourceforge.pmd.PmdAnalysis;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.rule.Rule;
import net.sourceforge.pmd.lang.rule.RuleSet;
import net.sourceforge.pmd.reporting.Report;
import net.sourceforge.pmd.renderers.Renderer;import net.sourceforge.pmd.*;
import net.sourceforge.pmd.lang.rule.*;
import net.sourceforge.pmd.reporting.*;
// Create PMD configuration
PMDConfiguration config = new PMDConfiguration();
config.setThreads(4);
config.addInputPath(Paths.get("src/main/java"));
config.addRuleSet("rulesets/java/quickstart.xml");
config.setReportFormat("text");
// Run analysis
try (PmdAnalysis analysis = PmdAnalysis.create(config)) {
// Add files for analysis
analysis.files().addDirectory(Paths.get("src/main/java"));
// Load rulesets
RuleSetLoader loader = analysis.newRuleSetLoader();
analysis.addRuleSet(loader.loadFromResource("rulesets/java/quickstart.xml"));
// Execute analysis and collect report
Report report = analysis.performAnalysisAndCollectReport();
// Process violations
List<RuleViolation> violations = report.getViolations();
for (RuleViolation violation : violations) {
System.out.printf("%s:%d - %s%n",
violation.getFilename(),
violation.getBeginLine(),
violation.getDescription());
}
System.out.printf("Found %d violations%n", violations.size());
}PMD Core is organized around several key architectural components:
PmdAnalysis orchestrates the complete analysis workflow from configuration to report generationPMDConfiguration and AbstractConfiguration handle runtime settings and optionsLanguage and LanguageRegistry provide modular support for different programming languagesRule, RuleSet, and related classes define and manage analysis rules with priorities and propertiesNode interface and related classes enable navigation and analysis of Abstract Syntax TreesReport, RuleViolation, and listener interfaces collect and structure analysis resultsRenderer implementations format reports for various output formats (XML, HTML, JSON, etc.)Main entry point for programmatic PMD analysis with comprehensive configuration options and lifecycle management.
// Primary analysis interface
class PmdAnalysis implements AutoCloseable {
static PmdAnalysis create(PMDConfiguration config);
FileCollector files();
RuleSetLoader newRuleSetLoader();
void addRuleSet(RuleSet ruleSet);
Report performAnalysisAndCollectReport();
void performAnalysis();
void close();
}
// Core configuration class
class PMDConfiguration extends AbstractConfiguration {
PMDConfiguration();
PMDConfiguration(LanguageRegistry languageRegistry);
void setThreads(int threads);
void addRuleSet(String rulesetPath);
void setMinimumPriority(RulePriority minimumPriority);
void setReportFormat(String reportFormat);
Renderer createRenderer();
}Comprehensive rule management system with priorities, properties, and lifecycle support for defining static analysis rules.
// Core rule interface
interface Rule extends PropertySource {
Language getLanguage();
void setLanguage(Language language);
String getName();
void setName(String name);
RulePriority getPriority();
void setPriority(RulePriority priority);
String getMessage();
void setMessage(String message);
void apply(Node target, RuleContext ctx);
Rule deepCopy();
}
// Rule priority enumeration
enum RulePriority {
HIGH(1), MEDIUM_HIGH(2), MEDIUM(3), MEDIUM_LOW(4), LOW(5);
int getPriority();
String getName();
static RulePriority valueOf(int priority);
}Modular language support system enabling PMD to analyze multiple programming languages with version-specific handling.
// Core language interface
interface Language extends Comparable<Language> {
String getName();
String getShortName();
String getId();
List<String> getExtensions();
boolean hasExtension(String extensionWithoutDot);
List<LanguageVersion> getVersions();
LanguageVersion getLatestVersion();
LanguageVersion getDefaultVersion();
boolean hasVersion(String version);
LanguageVersion getVersion(String version);
}
// Language registry for collections
final class LanguageRegistry implements Iterable<Language> {
static final LanguageRegistry PMD;
static final LanguageRegistry CPD;
LanguageRegistry(Set<? extends Language> languages);
Language getLanguageById(String langId);
Language getLanguageByFullName(String languageName);
}Abstract Syntax Tree navigation and processing capabilities for analyzing parsed source code structures.
// Core AST node interface
interface Node {
String getXPathNodeName();
Node getParent();
Node getChild(int index);
int getNumChildren();
List<? extends Node> getChildren();
Node getFirstChild();
Node getLastChild();
Node getNextSibling();
Node getPreviousSibling();
<T extends Node> List<T> findDescendantsOfType(Class<T> type);
<T extends Node> T getFirstDescendantOfType(Class<T> type);
NodeStream<? extends Node> descendants();
TextRegion getTextRegion();
String getText();
}Comprehensive reporting infrastructure for collecting violations, errors, and metrics with event-driven processing.
// Main report class
final class Report {
static Report buildReport(Consumer<? super FileAnalysisListener> lambda);
List<RuleViolation> getViolations();
List<SuppressedViolation> getSuppressedViolations();
List<ProcessingError> getProcessingErrors();
Report filterViolations(Predicate<RuleViolation> filter);
Report union(Report other);
ReportStats getStats();
boolean isEmpty();
}
// Rule violation interface
interface RuleViolation {
Rule getRule();
String getDescription();
boolean isSuppressed();
String getFilename();
int getBeginLine();
int getBeginColumn();
int getEndLine();
int getEndColumn();
}Extensible rendering framework for formatting analysis reports in various output formats including XML, HTML, JSON, and text.
// Core renderer interface
interface Renderer extends PropertySource {
String getName();
void setName(String name);
String getDescription();
String defaultFileExtension();
void setShowSuppressedViolations(boolean show);
void setWriter(Writer writer);
GlobalAnalysisListener newListener();
void start();
void end();
void flush();
}Type-safe configuration framework for rules and components with validation, serialization, and factory methods.
// Property source interface
interface PropertySource {
<T> T getProperty(PropertyDescriptor<T> propertyDescriptor);
<T> void setProperty(PropertyDescriptor<T> propertyDescriptor, T value);
boolean hasDescriptor(PropertyDescriptor<?> descriptor);
List<PropertyDescriptor<?>> getPropertyDescriptors();
Map<PropertyDescriptor<?>, Object> getPropertiesByPropertyDescriptor();
}
// Property descriptor interface
interface PropertyDescriptor<T> {
String name();
String description();
Class<T> type();
T defaultValue();
boolean isRequired();
T valueFrom(String propertyString);
String errorFor(T value);
}Specialized engine for detecting code duplications across files with configurable token-based analysis.
// Main CPD class
class CPD {
CPD(CPDConfiguration configuration);
void go();
Iterator<Match> getMatches();
int getNumberOfTokens(String file);
Map<String, Integer> getTokenCounts();
}
// Duplication match representation
final class Match {
int getTokenCount();
int getLineCount();
List<Mark> getMarkSet();
String getSourceCodeSlice();
}Essential utility classes for assertions, string manipulation, file handling, and other common operations.
// Assertion utilities
final class AssertionUtil {
static <T> T requireParamNotNull(String paramName, T param);
static <T> void requireContainsNoNullValue(String paramName, Collection<T> collection);
static AssertionError shouldNotReachHere();
static AssertionError shouldNotReachHere(String message);
}
// String manipulation utilities
final class StringUtil {
static boolean isEmpty(String str);
static boolean isNotEmpty(String str);
static boolean isBlank(String str);
static boolean isNotBlank(String str);
static List<String> split(String str, char separator);
}// Abstract base configuration
abstract class AbstractConfiguration {
Charset getSourceEncoding();
void setSourceEncoding(Charset sourceEncoding);
LanguagePropertyBundle getLanguageProperties(Language language);
LanguageRegistry getLanguageRegistry();
PmdReporter getReporter();
void setReporter(PmdReporter reporter);
LanguageVersion getForceLanguageVersion();
void setForceLanguageVersion(LanguageVersion version);
List<Path> getInputPathList();
void setInputPathList(List<Path> inputPaths);
void addInputPath(Path inputPath);
Path getReportFilePath();
void setReportFile(Path reportFile);
boolean isFailOnViolation();
void setFailOnViolation(boolean failOnViolation);
}
// File collection interface
interface FileCollector extends AutoCloseable {
void addFile(Path file);
void addDirectory(Path dir);
void addZipFile(Path zipFile);
void addSourceURI(URI uri);
List<TextFile> getCollectedFiles();
void filterLanguages(Set<Language> languages);
}
// Text file representation
interface TextFile {
FileId getFileId();
String getDisplayName();
LanguageVersion getLanguageVersion();
TextDocument readOnlyDocument();
void writeToPath(Path destination, Charset charset);
boolean isReadOnly();
}
// Rule set collection
class RuleSet implements ChecksumAware {
RuleSet(RuleSet rs);
static RuleSet forSingleRule(Rule rule);
static RuleSetBuilder create();
String getFileName();
String getName();
String getDescription();
List<Rule> getRules();
Rule getRuleByName(String ruleName);
boolean applies(FileId file);
boolean applies(LanguageVersion languageVersion);
int size();
Iterator<Rule> iterator();
}
// Rule set loading
final class RuleSetLoader {
static RuleSetLoader fromPmdConfig(PMDConfiguration configuration);
RuleSet loadFromResource(String ruleSetReferenceId);
List<RuleSet> loadFromResources(List<String> ruleSetReferenceIds);
RuleSetBuilder newRuleSetBuilder();
RuleSetLoader filterAbovePriority(RulePriority minimumPriority);
List<RuleSetLoadException> getLoadExceptions();
}
// Analysis listener interfaces
interface GlobalAnalysisListener extends AutoCloseable {
ListenerInitializer initializer();
FileAnalysisListener startFileAnalysis(TextFile file);
void onConfigError(Report.ConfigurationError error);
static GlobalAnalysisListener noop();
static GlobalAnalysisListener tee(List<? extends GlobalAnalysisListener> listeners);
}
interface FileAnalysisListener {
void onRuleViolation(RuleViolation violation);
void onSuppressedRuleViolation(Report.SuppressedViolation violation);
void onError(Report.ProcessingError error);
}
// Version information
final class PMDVersion {
static final String VERSION;
static String getNextMajorRelease();
static boolean isUnknown();
static boolean isSnapshot();
static String getFullVersionName();
}