0
# Core PMD Analysis
1
2
The Core PMD Analysis module provides the main entry point and configuration management for PMD static code analysis. It orchestrates the complete analysis workflow from configuration setup through rule execution to report generation.
3
4
## Capabilities
5
6
### PmdAnalysis
7
8
Main programmatic API for executing PMD analysis with comprehensive lifecycle management and resource handling.
9
10
```java { .api }
11
/**
12
* Main programmatic API for PMD analysis execution.
13
* Implements AutoCloseable for proper resource management.
14
*/
15
public final class PmdAnalysis implements AutoCloseable {
16
17
/**
18
* Create analysis instance from configuration
19
* @param config PMD configuration with analysis settings
20
* @return New PmdAnalysis instance ready for execution
21
*/
22
static PmdAnalysis create(PMDConfiguration config);
23
24
/**
25
* Get file collector for specifying analyzed sources
26
* @return FileCollector for adding files and directories
27
*/
28
FileCollector files();
29
30
/**
31
* Create new ruleset loader for loading rules from various sources
32
* @return RuleSetLoader configured with current settings
33
*/
34
RuleSetLoader newRuleSetLoader();
35
36
/**
37
* Add report renderer for output formatting
38
* @param renderer Renderer instance for specific output format
39
*/
40
void addRenderer(Renderer renderer);
41
42
/**
43
* Add multiple report renderers
44
* @param renderers Collection of renderer instances
45
*/
46
void addRenderers(Collection<Renderer> renderers);
47
48
/**
49
* Add analysis listener for custom event processing
50
* @param listener GlobalAnalysisListener for receiving events
51
*/
52
void addListener(GlobalAnalysisListener listener);
53
54
/**
55
* Add multiple analysis listeners
56
* @param listeners Collection of listener instances
57
*/
58
void addListeners(Collection<? extends GlobalAnalysisListener> listeners);
59
60
/**
61
* Add ruleset for analysis
62
* @param ruleSet RuleSet containing analysis rules
63
*/
64
void addRuleSet(RuleSet ruleSet);
65
66
/**
67
* Add multiple rulesets for analysis
68
* @param ruleSets Collection of RuleSet instances
69
*/
70
void addRuleSets(Collection<RuleSet> ruleSets);
71
72
/**
73
* Get unmodifiable view of currently loaded rulesets
74
* @return List of RuleSet instances
75
*/
76
List<RuleSet> getRulesets();
77
78
/**
79
* Get language-specific property bundle
80
* @param language Target language for properties
81
* @return LanguagePropertyBundle with language-specific settings
82
*/
83
LanguagePropertyBundle getLanguageProperties(Language language);
84
85
/**
86
* Get configurable file name renderer
87
* @return ConfigurableFileNameRenderer for customizing file path display
88
*/
89
ConfigurableFileNameRenderer fileNameRenderer();
90
91
/**
92
* Execute analysis without collecting results
93
* Results are sent to registered renderers and listeners
94
*/
95
void performAnalysis();
96
97
/**
98
* Execute analysis and return collected report
99
* @return Report containing all violations and errors
100
*/
101
Report performAnalysisAndCollectReport();
102
103
/**
104
* Get message reporter for logging and diagnostics
105
* @return PmdReporter for handling messages
106
*/
107
PmdReporter getReporter();
108
109
/**
110
* Run analysis and return statistics
111
* @return ReportStats with violation and error counts
112
*/
113
ReportStats runAndReturnStats();
114
115
/**
116
* Close analysis instance and cleanup resources
117
*/
118
void close();
119
}
120
```
121
122
**Usage Examples:**
123
124
```java
125
import net.sourceforge.pmd.*;
126
import net.sourceforge.pmd.lang.rule.*;
127
import java.nio.file.Paths;
128
129
// Basic analysis setup
130
PMDConfiguration config = new PMDConfiguration();
131
config.addInputPath(Paths.get("src/main/java"));
132
133
try (PmdAnalysis analysis = PmdAnalysis.create(config)) {
134
// Add files for analysis
135
analysis.files().addDirectory(Paths.get("src/main/java"));
136
137
// Load and add rules
138
RuleSetLoader loader = analysis.newRuleSetLoader();
139
RuleSet javaRules = loader.loadFromResource("rulesets/java/quickstart.xml");
140
analysis.addRuleSet(javaRules);
141
142
// Execute and get report
143
Report report = analysis.performAnalysisAndCollectReport();
144
145
System.out.printf("Found %d violations%n", report.getViolations().size());
146
}
147
148
// Analysis with custom renderer
149
try (PmdAnalysis analysis = PmdAnalysis.create(config)) {
150
// Add custom XML renderer
151
XMLRenderer xmlRenderer = new XMLRenderer();
152
xmlRenderer.setWriter(new FileWriter("report.xml"));
153
analysis.addRenderer(xmlRenderer);
154
155
// Add files and rules
156
analysis.files().addDirectory(Paths.get("src"));
157
analysis.addRuleSets(loader.loadFromResources(Arrays.asList(
158
"rulesets/java/quickstart.xml",
159
"rulesets/java/design.xml"
160
)));
161
162
// Execute analysis (results go to renderer)
163
analysis.performAnalysis();
164
}
165
```
166
167
### PMDConfiguration
168
169
Runtime configuration class for PMD analysis with comprehensive settings for threading, rulesets, reporting, and caching.
170
171
```java { .api }
172
/**
173
* Runtime configuration for PMD analysis.
174
* Extends AbstractConfiguration with PMD-specific settings.
175
*/
176
public class PMDConfiguration extends AbstractConfiguration {
177
178
/** Default violation suppress marker */
179
public static final String DEFAULT_SUPPRESS_MARKER = "NOPMD";
180
181
/**
182
* Default constructor with PMD language registry
183
*/
184
PMDConfiguration();
185
186
/**
187
* Constructor with custom language registry
188
* @param languageRegistry Registry of supported languages
189
*/
190
PMDConfiguration(LanguageRegistry languageRegistry);
191
192
/**
193
* Get violation suppress marker (default "NOPMD")
194
* @return String used to suppress violations in comments
195
*/
196
String getSuppressMarker();
197
198
/**
199
* Set violation suppress marker
200
* @param suppressMarker String to use for suppressing violations
201
*/
202
void setSuppressMarker(String suppressMarker);
203
204
/**
205
* Get number of processing threads
206
* @return Number of threads for parallel analysis
207
*/
208
int getThreads();
209
210
/**
211
* Set number of processing threads
212
* @param threads Number of threads (must be positive)
213
*/
214
void setThreads(int threads);
215
216
/**
217
* Get ClassLoader for rule processing
218
* @return ClassLoader used for loading rules and dependencies
219
*/
220
ClassLoader getClassLoader();
221
222
/**
223
* Set ClassLoader for rule processing
224
* @param classLoader ClassLoader to use for rule loading
225
*/
226
void setClassLoader(ClassLoader classLoader);
227
228
/**
229
* Prepend auxiliary classpath for type resolution
230
* @param classpath Classpath string to prepend
231
*/
232
void prependAuxClasspath(String classpath);
233
234
/**
235
* Get ruleset paths
236
* @return List of ruleset reference paths
237
*/
238
@NonNull List<@NonNull String> getRuleSetPaths();
239
240
/**
241
* Set ruleset paths
242
* @param ruleSetPaths List of ruleset references (files, resources, URLs)
243
*/
244
void setRuleSets(@NonNull List<@NonNull String> ruleSetPaths);
245
246
/**
247
* Add single ruleset path
248
* @param rulesetPath Path to ruleset (file, resource, or URL)
249
*/
250
void addRuleSet(@NonNull String rulesetPath);
251
252
/**
253
* Get minimum rule priority threshold
254
* @return Minimum RulePriority for violations
255
*/
256
RulePriority getMinimumPriority();
257
258
/**
259
* Set minimum rule priority threshold
260
* @param minimumPriority Minimum priority for reporting violations
261
*/
262
void setMinimumPriority(RulePriority minimumPriority);
263
264
/**
265
* Create renderer without writer
266
* @return Renderer instance based on report format setting
267
*/
268
Renderer createRenderer();
269
270
/**
271
* Create renderer with optional writer
272
* @param withReportWriter Whether to configure writer from reportFile setting
273
* @return Configured renderer instance
274
*/
275
Renderer createRenderer(boolean withReportWriter);
276
277
/**
278
* Get report format name
279
* @return String identifier for output format (xml, html, text, etc.)
280
*/
281
String getReportFormat();
282
283
/**
284
* Set report format name
285
* @param reportFormat Format identifier (xml, html, json, text, etc.)
286
*/
287
void setReportFormat(String reportFormat);
288
289
/**
290
* Check if suppressed violations are shown in reports
291
* @return true if suppressed violations are included in output
292
*/
293
boolean isShowSuppressedViolations();
294
295
/**
296
* Set whether to show suppressed violations in reports
297
* @param show true to include suppressed violations in output
298
*/
299
void setShowSuppressedViolations(boolean show);
300
301
/**
302
* Get renderer configuration properties
303
* @return Properties for configuring renderer behavior
304
*/
305
Properties getReportProperties();
306
307
/**
308
* Set renderer configuration properties
309
* @param reportProperties Properties for renderer configuration
310
*/
311
void setReportProperties(Properties reportProperties);
312
313
/**
314
* Set analysis cache file location
315
* @param cacheLocation Path to cache file for incremental analysis
316
*/
317
void setAnalysisCacheLocation(String cacheLocation);
318
319
/**
320
* Disable incremental analysis caching
321
* @param noCache true to disable caching, false to enable
322
*/
323
void setIgnoreIncrementalAnalysis(boolean noCache);
324
325
/**
326
* Check if incremental analysis is disabled
327
* @return true if caching is disabled
328
*/
329
boolean isIgnoreIncrementalAnalysis();
330
}
331
```
332
333
**Usage Examples:**
334
335
```java
336
import net.sourceforge.pmd.*;
337
import net.sourceforge.pmd.lang.rule.RulePriority;
338
import java.nio.file.Paths;
339
import java.util.Properties;
340
341
// Basic configuration
342
PMDConfiguration config = new PMDConfiguration();
343
config.setThreads(Runtime.getRuntime().availableProcessors());
344
config.addInputPath(Paths.get("src/main/java"));
345
config.addRuleSet("rulesets/java/quickstart.xml");
346
config.setReportFormat("xml");
347
config.setReportFile(Paths.get("pmd-report.xml"));
348
349
// Advanced configuration with custom settings
350
PMDConfiguration config = new PMDConfiguration();
351
config.setThreads(4);
352
config.setSuppressMarker("NOSONAR"); // Use SonarQube-style suppression
353
config.setMinimumPriority(RulePriority.MEDIUM); // Only medium+ priority violations
354
355
// Add multiple rulesets
356
config.addRuleSet("rulesets/java/quickstart.xml");
357
config.addRuleSet("rulesets/java/design.xml");
358
config.addRuleSet("custom-rules.xml");
359
360
// Configure caching for performance
361
config.setAnalysisCacheLocation("target/pmd-cache");
362
363
// Configure HTML renderer with custom properties
364
config.setReportFormat("html");
365
Properties htmlProps = new Properties();
366
htmlProps.setProperty("linkPrefix", "https://github.com/repo/blob/main/");
367
htmlProps.setProperty("linePrefix", "#L");
368
config.setReportProperties(htmlProps);
369
370
// Show suppressed violations for debugging
371
config.setShowSuppressedViolations(true);
372
373
// Create and configure renderer
374
Renderer renderer = config.createRenderer(true); // with writer from reportFile
375
renderer.start();
376
// ... analysis execution
377
renderer.end();
378
```
379
380
### AbstractConfiguration
381
382
Base configuration class providing common settings for PMD and CPD with language handling, file management, and reporting options.
383
384
```java { .api }
385
/**
386
* Base configuration class for PMD and CPD with common settings.
387
* Provides language handling, file management, and basic reporting configuration.
388
*/
389
public abstract class AbstractConfiguration {
390
391
/**
392
* Get source file encoding
393
* @return Charset used for reading source files
394
*/
395
Charset getSourceEncoding();
396
397
/**
398
* Set source file encoding
399
* @param sourceEncoding Charset for reading source files
400
*/
401
void setSourceEncoding(Charset sourceEncoding);
402
403
/**
404
* Get language-specific property bundle
405
* @param language Target language for properties
406
* @return LanguagePropertyBundle with language-specific settings
407
*/
408
@NonNull LanguagePropertyBundle getLanguageProperties(Language language);
409
410
/**
411
* Get language registry
412
* @return LanguageRegistry of supported languages
413
*/
414
LanguageRegistry getLanguageRegistry();
415
416
/**
417
* Get message reporter for diagnostics and logging
418
* @return PmdReporter for handling messages
419
*/
420
@NonNull PmdReporter getReporter();
421
422
/**
423
* Set message reporter
424
* @param reporter PmdReporter for handling messages
425
*/
426
void setReporter(@NonNull PmdReporter reporter);
427
428
/**
429
* Get language version discoverer for file type detection
430
* @return LanguageVersionDiscoverer for automatic language detection
431
*/
432
LanguageVersionDiscoverer getLanguageVersionDiscoverer();
433
434
/**
435
* Get forced language version (overrides auto-detection)
436
* @return LanguageVersion if forced, null for auto-detection
437
*/
438
LanguageVersion getForceLanguageVersion();
439
440
/**
441
* Check if language version is forced
442
* @return true if language version is explicitly set
443
*/
444
boolean isForceLanguageVersion();
445
446
/**
447
* Force specific language version for all files
448
* @param version LanguageVersion to use, or null for auto-detection
449
*/
450
void setForceLanguageVersion(@Nullable LanguageVersion version);
451
452
/**
453
* Limit analysis to specific language only
454
* @param lang Language to restrict analysis to
455
*/
456
void setOnlyRecognizeLanguage(Language lang);
457
458
/**
459
* Set default language version
460
* @param languageVersion Default version for language
461
*/
462
void setDefaultLanguageVersion(LanguageVersion languageVersion);
463
464
/**
465
* Set multiple default language versions
466
* @param versions List of default language versions
467
*/
468
void setDefaultLanguageVersions(List<LanguageVersion> versions);
469
470
/**
471
* Get language version for specific file
472
* @param fileName Name of file to check
473
* @return LanguageVersion for file, or null if not recognized
474
*/
475
@Nullable LanguageVersion getLanguageVersionOfFile(String fileName);
476
477
/**
478
* Add path for relativizing/shortening report paths
479
* @param path Root path for making relative paths in reports
480
*/
481
void addRelativizeRoot(Path path);
482
483
/**
484
* Add multiple relativize root paths
485
* @param paths List of root paths for relativizing reports
486
*/
487
void addRelativizeRoots(List<Path> paths);
488
489
/**
490
* Get relativize root paths
491
* @return List of paths used for shortening report paths
492
*/
493
List<Path> getRelativizeRoots();
494
495
/**
496
* Get input URI
497
* @return URI for input source
498
*/
499
URI getUri();
500
501
/**
502
* Set input URI
503
* @param inputUri URI for input source
504
*/
505
void setInputUri(URI inputUri);
506
507
/**
508
* Get input paths for analysis
509
* @return List of paths to analyze
510
*/
511
@NonNull List<Path> getInputPathList();
512
513
/**
514
* Set input paths for analysis
515
* @param inputPaths List of paths to analyze
516
*/
517
void setInputPathList(List<Path> inputPaths);
518
519
/**
520
* Add input path for analysis
521
* @param inputPath Path to add for analysis
522
*/
523
void addInputPath(@NonNull Path inputPath);
524
525
/**
526
* Get input file list path (file containing paths to analyze)
527
* @return Path to file containing input paths, or null
528
*/
529
@Nullable Path getInputFile();
530
531
/**
532
* Get ignore file list path (file containing paths to ignore)
533
* @return Path to file containing ignore patterns, or null
534
*/
535
@Nullable Path getIgnoreFile();
536
537
/**
538
* Set input file list path
539
* @param inputFilePath Path to file containing input paths
540
*/
541
void setInputFilePath(Path inputFilePath);
542
543
/**
544
* Set ignore file list path
545
* @param ignoreFilePath Path to file containing ignore patterns
546
*/
547
void setIgnoreFilePath(Path ignoreFilePath);
548
549
/**
550
* Get exclude patterns
551
* @return List of paths/patterns to exclude from analysis
552
*/
553
List<Path> getExcludes();
554
555
/**
556
* Set exclude patterns
557
* @param excludes List of paths/patterns to exclude
558
*/
559
void setExcludes(List<Path> excludes);
560
561
/**
562
* Check if files are collected recursively
563
* @return true if directories are processed recursively
564
*/
565
boolean collectFilesRecursively();
566
567
/**
568
* Set recursive file collection
569
* @param collectRecursive true to process directories recursively
570
*/
571
void collectFilesRecursively(boolean collectRecursive);
572
573
/**
574
* Get report file path
575
* @return Path for output report file, or null for stdout
576
*/
577
@Nullable Path getReportFilePath();
578
579
/**
580
* Set report file path
581
* @param reportFile Path for output report file, or null for stdout
582
*/
583
void setReportFile(@Nullable Path reportFile);
584
585
/**
586
* Check if analysis should fail on violations
587
* @return true if violations cause analysis failure
588
*/
589
boolean isFailOnViolation();
590
591
/**
592
* Set whether to fail analysis on violations
593
* @param failOnViolation true to fail analysis on violations
594
*/
595
void setFailOnViolation(boolean failOnViolation);
596
597
/**
598
* Check if analysis should fail on errors
599
* @return true if processing errors cause analysis failure
600
*/
601
boolean isFailOnError();
602
603
/**
604
* Set whether to fail analysis on processing errors
605
* @param failOnError true to fail analysis on processing errors
606
*/
607
void setFailOnError(boolean failOnError);
608
}
609
```
610
611
## Types
612
613
```java { .api }
614
/**
615
* File collection interface for managing analysis inputs
616
*/
617
interface FileCollector extends AutoCloseable {
618
void addFile(Path file);
619
void addDirectory(Path dir);
620
void addZipFile(Path zipFile);
621
void addSourceURI(URI uri);
622
List<TextFile> getCollectedFiles();
623
void filterLanguages(Set<Language> languages);
624
void close();
625
}
626
627
/**
628
* Configurable file name renderer for customizing path display
629
*/
630
interface ConfigurableFileNameRenderer {
631
String getDisplayName(FileId fileId);
632
void setRelativizeRoots(List<Path> roots);
633
}
634
635
/**
636
* Language property bundle for language-specific settings
637
*/
638
interface LanguagePropertyBundle extends PropertySource {
639
Language getLanguage();
640
LanguagePropertyBundle copyForLanguage(Language language);
641
}
642
643
/**
644
* Report statistics summary
645
*/
646
interface ReportStats {
647
int getNumViolations();
648
int getNumErrors();
649
int getNumProcessingErrors();
650
int getNumConfigErrors();
651
Map<String, Integer> getViolationsByRule();
652
Map<String, Integer> getViolationsByFile();
653
}
654
655
/**
656
* Message reporter for diagnostics and logging
657
*/
658
interface PmdReporter {
659
void logEx(Level level, String message, Object[] formatArgs, Throwable error);
660
void log(Level level, String message, Object... formatArgs);
661
void warn(String message, Object... formatArgs);
662
void error(String message, Object... formatArgs);
663
boolean isLoggable(Level level);
664
}
665
```