PMD Integration with DefectDojo
PMD Integration with DefectDojo
PMD is an open source static source code analyzer maintained by the PMD project. It is best known for Java and Salesforce Apex, and also supports languages including JavaScript, Kotlin, Swift, Scala, PL/SQL, Visualforce, XML, and others. PMD applies rulesets grouped into categories such as best practices, design, error prone, performance, and security, and reports violations with a priority from 1 (high) to 5 (low). It can write reports in several formats, including CSV, which is the format DefectDojo imports.
PMD Integration with DefectDojo
We already run PMD in our Java and Apex builds, mostly for code quality, with a few security-relevant rules switched on. Importing its CSV into DefectDojo lets us treat the violations we care about as tracked Findings with owners and due dates, next to the output of our dedicated security scanners. It also means a rule we have decided to tolerate in one module can be risk-accepted once, with a reason, rather than argued about in every code review.
Why PMD Matters
PMD isn't a dedicated vulnerability scanner, but plenty of security problems start as code quality problems.
- Error prone rules catch issues such as unclosed resources and empty catch blocks, which can turn into reliability or information disclosure problems.
- For Salesforce Apex, PMD's security category covers platform-specific issues such as missing sharing declarations and CRUD or FLS checks.
- Rulesets are configurable, so teams can start with a small set and add rules over time.
- It runs from the command line, Maven, Gradle, and many IDEs, so developers can see the same results locally.
- Large codebases can produce thousands of violations. Without triage and tracking, the important ones are hard to find.
Advantages of This Integration
What we get from sending PMD results through DefectDojo:
- Rule, file, and line on every Finding. Each CSV row becomes a Finding with the rule name in the title and the file path and line recorded, so developers can go straight to the code.
- Decisions that persist. False positive marking and risk acceptance live in DefectDojo, so the team doesn't need to scatter suppression annotations through the code to keep a decision.
- Reimport lifecycle. Reimporting into the same Test mitigates violations that were fixed and adds new ones.
- SLAs and assignment. PMD Findings fall under the same SLA, assignment, and Jira workflow as Findings from other SAST tools.
- One view per application. Code quality Findings sit on the same Asset as security scanner Findings, so leads can see both when planning remediation work.
How This Integration Works
DefectDojo imports PMD results with the PMD Scan scan type.
1. Produce a CSV report. With PMD 7, run pmd check with a ruleset and CSV output:
pmd check -d src/main/java -R rulesets/java/quickstart.xml \
-f csv -r pmd-report.csv -z .
-z (--relativize-paths-with) writes file paths relative to the given directory, which keeps paths stable between build agents. The parser expects PMD's CSV columns: Problem, Package, File, Priority, Line, Description, Rule set, and Rule.
2. Import it. In the UI, open the Engagement, choose Import Scan Results, select PMD Scan, and upload the CSV. For automation, use the API, available in Community Edition and DefectDojo Pro:
curl "https://YOUR_INSTANCE/api/v2/import-scan/" \
-H "Authorization: Token $DD_API_TOKEN" \
-F "scan_type=PMD Scan" \
-F "file=@pmd-report.csv" \
-F "product_name=claims-service" \
-F "engagement_name=CI" \
-F "auto_create_context=true"
DefectDojo Pro users can run the same import with Universal Importer:
universal-importer import \
--defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/" \
--scan-type "PMD Scan" \
--report-path "./pmd-report.csv" \
--product-name "claims-service" \
--engagement-name "CI" \
--auto-create-context
3. Reimport on each build. Send later reports to /api/v2/reimport-scan/ against the same Test, rather than creating a new Test per build.
Data Granularity: What Gets Imported
The parser creates one Finding per CSV row.
| DefectDojo Field | Source in PMD CSV | Notes |
|---|---|---|
| Title | Rule |
Formatted as PMD rule RuleName, for example PMD rule CloseResource |
| Severity | Priority |
5 Critical, 4 High, 3 Medium, 2 Low, 1 Info. This is the reverse of PMD's own scale |
| Description | Description, Rule set, Problem, Package |
Labeled lines; Problem is the row number in the report |
| File Path | File |
As PMD wrote it |
| Line | Line |
Line of the violation |
| Impact | Fixed text | Always "No impact provided" |
| Mitigation | Fixed text | Always "No mitigation provided" |
| Finding type | Not set by parser | DefectDojo's default (dynamic) applies, even though PMD is static analysis |
| Deduplication | Legacy algorithm | No per-scanner config; hash falls back to title, CWE, line, file path, description |
PMD doesn't report CWE in its CSV, so no CWE is set.
Use Cases
For Salesforce Apex projects: Teams building on Salesforce run PMD's Apex security rules in CI and reimport into a Test per package. Sharing and CRUD/FLS violations get owners and SLAs alongside the rest of the org's application security work.
When adding security rules to an existing PMD setup: A Java team already running PMD for code quality adds error prone and security categories, imports the first CSV as a baseline, marks accepted patterns as false positives, and tracks only new violations from then on.
For code review support: Reviewers check the DefectDojo Test for a branch's new PMD Findings, with file and line, instead of searching a long build log.
For engineering metrics: Leads compare open PMD Findings across Assets to decide where refactoring time is most needed, with security scanner results on the same Assets for context.
Operational Tips
- Correct for the priority mapping. PMD priority 1 is its highest and 5 its lowest, but the parser maps 5 to Critical and 1 to Info. Expect PMD's most important violations to arrive as Info. Adjust severities during triage, or align rule priorities in your ruleset so the result is what you intend, before setting SLAs on PMD Findings.
- Don't apply
minimum_severityto PMD imports until you've checked how your ruleset's priorities land. A threshold can drop your highest-priority rules. - The description includes PMD's row number (
Problem), which shifts whenever violations are added or removed earlier in the report. That makes cross-Test deduplication unreliable, so reimport into one Test per codebase instead of importing a new Test each build. - Use
-zso file paths are relative and consistent. Absolute paths that differ per build agent change the hash. - Keep the ruleset focused. Importing every style rule can bury the security-relevant ones; a separate PMD run with just the categories you want to track keeps the Test useful.
- Tag imports with the ruleset or language (for example
tags=pmd-apex-security) if you track more than one PMD configuration on an Asset.