Quick Verdict
Semgrep and PMD both analyze Java code statically, but they solve fundamentally different problems and operate at different depths. PMD is a free, open-source static analysis tool built into the Java build ecosystem - you add the maven-pmd-plugin to your pom.xml, configure a ruleset, and PMD checks your Java source code for code quality violations: naming convention breaches, cyclomatic complexity, unused variables, empty catch blocks, and structural anti-patterns. PMD is primarily a code quality tool with limited security coverage.
Semgrep is a programmable, multi-language security SAST platform with cross-file taint tracking, custom YAML rule authoring, AI-powered triage, and a registry of 20,000+ Pro rules spanning 30+ languages. For Java, Semgrep traces user input from Spring controller methods through service layers to JDBC calls, detects framework-specific vulnerabilities in Spring Boot, Spring MVC, and Jakarta EE applications, and lets teams encode custom organization security policies as rules in hours.
The reason this comparison matters is that Java teams frequently encounter both tools in their security and code quality toolchain. PMD is a default inclusion in many Java projects. Semgrep is increasingly the recommended SAST tool for Java applications. Understanding where each tool is strong, where each falls short, and how to use them together is essential for Java teams building a practical static analysis program.
Choose PMD alone if: your primary need is Java code quality enforcement - naming conventions, complexity limits, unused code detection, and structural anti-pattern checking - in a Maven or Gradle build with zero tooling cost and no additional infrastructure.
Choose Semgrep alone if: your primary need is Java security SAST with cross-file taint tracking, Spring framework vulnerability detection, custom security rules, multi-language support, and AI-powered false positive triage.
The best setup for most Java teams: Run PMD inside your Maven or Gradle build for code quality enforcement. Run Semgrep in CI/CD for security SAST with taint tracking, framework rules, and custom organizational checks. They are complementary tools with minimal overlap - PMD handles code quality, Semgrep handles security.
At-a-Glance Comparison
| Category | Semgrep | PMD |
|---|---|---|
| Primary focus | Security SAST with custom rules | Java code quality and style |
| Languages | 30+ (Java, Python, JS, Go, Ruby, C, etc.) | 16 (Java-first, others shallower) |
| Built-in rules | 2,800+ community / 20,000+ Pro | 400+ Java rules, 200+ other languages |
| Custom rules | YAML - mirrors target language syntax | XML rulesets + XPath or Java plugins |
| Cross-file analysis | Yes (Pro engine, paid tier) | No - single file only |
| Taint tracking | Yes (Pro engine) | No |
| Security focus | Primary purpose | Secondary - limited security rules |
| Code quality focus | Not primary purpose | Primary purpose |
| Spring Boot rules | Yes - extensive framework-specific rules | Limited - general Java patterns |
| AI triage | Yes - Semgrep Assistant (20-40% noise reduction) | No |
| Maven integration | Via docker or CLI step in CI | Native - maven-pmd-plugin in pom.xml |
| Gradle integration | Via CLI or Docker | Native - PMD Gradle plugin |
| IDE integration | VS Code extension, IntelliJ plugin | IntelliJ, Eclipse, NetBeans plugins |
| Pricing | OSS CLI free; full platform free for 10 contributors | Completely free, always |
| Paid pricing | $35/contributor/month (Team tier) | No paid tier |
| License | LGPL-2.1 (OSS) / commercial (Pro) | BSD 4-clause / Apache 2.0 |
| False positive handling | AI triage (paid) + taint context | Manual suppression via ruleset config |
| SCA / dependency scanning | Yes - Semgrep Supply Chain (Pro) | No |
| Secrets detection | Yes - Semgrep Secrets (Pro) | No |
| Apex (Salesforce) support | Limited | Strong - one of few tools with Apex rules |
What Is PMD?
PMD is a free, open-source static analysis tool that has been part of the Java ecosystem since 2002. Originally built for Java, PMD 7.x supports 16 languages including Kotlin, Apex, and JavaScript. For Java specifically, PMD offers hundreds of rules organized into categories:
- Best Practices: Avoiding unnecessary object creation, proper use of StringBuilder, avoiding deprecated API usage, proper use of try-with-resources
- Code Style: Naming conventions for classes, methods, fields, and variables, line length limits, brace placement
- Design: Cyclomatic complexity (CyclomaticComplexity rule), God Class detection, Law of Demeter violations, deeply nested if statements
- Documentation: Missing Javadoc on public classes and methods
- Error Prone: Empty catch blocks, broken null checks, assignment in operands, suspicious import patterns
- Multithreading: Unsafe use of static fields in multithreaded contexts, incorrect double-checked locking
- Performance: Inefficient string operations, unnecessary wrapper object creation, avoiding loops where streams apply
- Security: Limited - hardcoded IVs, unsafe use of System.exit, some injection-prone string patterns
PMD integrates directly into the Java build lifecycle through the maven-pmd-plugin and the Gradle PMD plugin. This tight build integration is one of PMD's strongest properties: violations appear as build failures with no additional CI configuration needed. A developer sees PMD violations in the same build output as compilation errors, keeping the feedback loop tight.
PMD's rule configuration uses XML rulesets. You can use PMD's built-in rulesets directly (rulesets/java/quickstart.xml), create a custom ruleset that references specific rules by name, or write custom XPath-based rules that detect patterns in PMD's Java AST. PMD 7.x improved the XPath rule experience with better documentation and tooling, making custom rule authoring more accessible than in earlier versions - though it still requires learning PMD's AST structure and XPath syntax.
The key limitation of PMD for Java security work is architectural. PMD performs single-file analysis: it builds an AST of one Java file at a time and checks it against configured rules. It has no awareness of what other classes do, what values methods return from other packages, or how data flows across class and package boundaries. This single-file limitation means PMD cannot detect the injection vulnerabilities that characterize real-world Java applications where user input flows from a Spring controller through a service class to a JDBC call.
PMD's security category exists and catches obvious patterns, but it cannot perform the dataflow analysis required to catch injection vulnerabilities in well-architected Spring applications. For Java security analysis beyond basic pattern matching, a dedicated SAST tool is required.
What Is Semgrep?
Semgrep is a multi-language, programmable static analysis engine built for application security. Originally developed at Facebook and now maintained by Semgrep, Inc. (formerly r2c), Semgrep's core design principle is that security rules should look like the code they analyze - making rules readable, writable, and maintainable by application developers rather than only security specialists.
Semgrep operates across three tiers:
Community Edition (free, open source): The core Semgrep engine under LGPL-2.1. Performs single-file and single-function analysis. Includes the community registry with 2,800+ rules covering Java, Python, JavaScript, Go, Ruby, C, C++, and 25+ other languages. Runs as a CLI with no login required and no data sent to the cloud.
Team tier ($35/contributor/month, free for up to 10 contributors): The full Semgrep AppSec Platform. Adds cross-file dataflow analysis, the Pro engine with taint tracking across class and package boundaries, Semgrep Assistant (AI-powered triage), 20,000+ Pro rules, centralized dashboards, Semgrep Supply Chain (SCA with reachability analysis), and Semgrep Secrets (credential detection with validation).
Enterprise (custom pricing): SSO/SAML, custom deployment options, advanced compliance reporting, dedicated support, and SLA guarantees.
For Java specifically, Semgrep's rule registry includes:
- Spring Boot and Spring MVC rules: Missing @PreAuthorize annotations, unsafe SpEL with user input, CSRF disabled in Spring Security, insecure CORS configuration, missing authentication in filter chains
- JDBC and JPA rules: Raw SQL string concatenation, unsafe use of createNativeQuery() with user input, PreparedStatement misuse
- Java deserialization rules: Unsafe ObjectInputStream.readObject() with untrusted data, use of vulnerable deserialization libraries
- Java cryptography rules: Weak cipher modes (ECB), hardcoded cryptographic keys, insecure random number generation with java.util.Random
- OWASP Top 10 Java coverage: SQL injection, XSS, command injection, path traversal, XML injection, SSRF patterns
The defining capability for Java security is Semgrep's Pro engine taint tracking. A taint rule specifies sources (where untrusted data enters the application - Spring @RequestParam, @PathVariable, HttpServletRequest.getParameter(), etc.) and sinks (dangerous operations that must not receive untrusted data - JDBC execute(), Runtime.exec(), etc.). Semgrep traces data from any source to any sink across all Java files in the project, following it through variable assignments, method calls, constructor invocations, and service class boundaries.
For a detailed review of Semgrep's full capability set and pricing structure, see our Semgrep review.
Feature-by-Feature Breakdown
Java Security Rule Coverage
This is the dimension where the tools diverge most sharply, and where the choice between them matters most for Java security programs.
PMD's security coverage is pattern-based and shallow. PMD's Security ruleset flags obvious, high-confidence patterns: use of hardcoded cryptographic initialization vectors, calls to System.exit() in library code, some string-formatting patterns that may indicate injection risk, and import of dangerous classes. These checks are useful but limited. The critical constraint is that PMD cannot perform dataflow analysis. Consider this typical Spring MVC application:
// UserController.java
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users/search")
public List<User> searchUsers(@RequestParam String name) {
return userService.findByName(name); // user input flows here
}
}
// UserService.java
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> findByName(String name) {
return userRepository.searchByName(name); // taint continues
}
}
// UserRepository.java
public class UserRepository {
@PersistenceContext
private EntityManager entityManager;
public List<User> searchByName(String name) {
// SQL injection: user input reaches native query
String sql = "SELECT * FROM users WHERE name LIKE '%" + name + "%'";
return entityManager.createNativeQuery(sql, User.class).getResultList();
}
}
PMD sees three separate files. In UserController.java, it sees a @RequestParam parameter assigned to a variable. In UserService.java, it sees a method call. In UserRepository.java, it may flag the string concatenation pattern - but it cannot confirm that the variable name originated from user input in the controller. PMD's analysis stops at file boundaries. Semgrep's Pro engine traces the taint from @RequestParam String name (source) through the service layer to createNativeQuery(sql) (sink), confirming the SQL injection vulnerability across the full call chain.
Semgrep's Java security coverage extends across the full application stack. Beyond the Spring example above, Semgrep adds rules for Jakarta EE (formerly Java EE) security patterns, Hibernate and JPA native query misuse, Java command injection via ProcessBuilder and Runtime.exec(), Java XML injection (XXE via DocumentBuilderFactory without external entity disabling), Java deserialization vulnerabilities, Spring Security configuration weaknesses, and Java cryptography misuse (ECB mode, static IVs, seeded random). The framework-specific rules understand the APIs your Java application actually uses rather than relying on generic string-pattern matching.
Custom Rule Authoring
For Java organizations with internal security standards, this is often the deciding dimension.
PMD custom rules require technical depth. To extend PMD with a custom Java rule, you have two options. The first is XPath-based rules: write an XPath expression against PMD's Java AST, embed it in a ruleset XML file, and deploy it. This requires learning PMD's AST node structure (which is documented but not intuitive) and XPath syntax. The second is Java plugin rules: write a Java class that extends AbstractJavaRule, implement visit() methods for AST node types, and package the class into a JAR that PMD loads at runtime. This requires Java development skills and understanding of PMD's internal API. Neither approach is accessible to developers who have not specifically studied PMD's extension mechanisms.
Semgrep custom rules are readable by any Java developer. A Semgrep YAML rule pattern looks like the Java code it matches, with metavariable placeholders for the parts you want to match generically. A rule to detect an organization-internal anti-pattern - say, direct use of JDBC without going through the organization's audited database wrapper - looks like this:
rules:
- id: use-approved-db-wrapper
patterns:
- pattern: |
DriverManager.getConnection(...)
- pattern-not: |
com.myorg.db.ApprovedConnectionFactory.getConnection(...)
message: >
Direct use of DriverManager.getConnection() bypasses the organization's
ApprovedConnectionFactory, which enforces connection pooling, encryption,
and audit logging. Use ApprovedConnectionFactory.getConnection() instead.
severity: ERROR
languages: [java]
metadata:
category: security
confidence: HIGH
A Java developer who has never seen Semgrep before can read this rule, understand what it checks, and modify it in minutes. Writing a new rule from scratch takes 15-30 minutes for a developer encountering Semgrep for the first time. The Semgrep Playground at semgrep.dev allows interactive rule development and testing against sample code before deployment. This accessibility transforms how organizations can encode internal security standards - requirements like "all file I/O must go through the FileAccessAuditService" or "all external HTTP calls must use the organization's HttpClientFactory" can be enforced as Semgrep rules, reviewed by developers, and deployed organization-wide.
Cross-File Analysis and Taint Tracking
This is the most technically significant difference between Semgrep and PMD for Java security programs.
PMD's analysis is strictly single-file. This is a fundamental architectural property of PMD, not a configuration option. PMD builds an AST of one Java source file at a time, runs configured rules against that AST, and outputs violations. It has no mechanism to follow method calls across class boundaries or track data flow between files. No version of PMD and no PMD configuration enables cross-file analysis.
Semgrep's Pro engine performs cross-file, cross-class taint analysis for Java. The taint-tracking mode traces data from configured sources to configured sinks across the entire Java project. Sources include:
- Spring MVC:
@RequestParam,@PathVariable,@RequestBody,HttpServletRequest.getParameter(),HttpServletRequest.getHeader() - JAX-RS:
@QueryParam,@PathParam,@HeaderParam,@FormParam - Servlet:
HttpServletRequest.getInputStream(),HttpServletRequest.getReader() - External data: file reads, environment variables, system properties, external API responses
Sinks include:
- SQL execution:
Statement.execute(),PreparedStatementwith string concatenation,EntityManager.createNativeQuery(),JdbcTemplate.queryForList()with string building - Command execution:
Runtime.exec(),ProcessBuilderwith user-controlled args - File access:
new File()orPaths.get()with user-controlled path components - Reflection:
Class.forName()with user input,Method.invoke()with user-controlled method names - Deserialization:
ObjectInputStream.readObject()with untrusted streams
Semgrep follows the taint from any source to any sink, tracking it through variable assignments, method return values, constructor calls, and class boundaries across the entire codebase. This is how real injection vulnerabilities in production Java applications are actually detected.
False Positive Rates and Noise Management
False positives determine whether developers actually trust and act on static analysis findings. A tool with high false positive rates trains developers to ignore findings.
PMD's false positives in security categories are structurally unavoidable. Because PMD's security rules are pattern-based rather than context-aware, they flag patterns that match regardless of whether the matched code is actually dangerous. A rule that flags string concatenation near a word like "SELECT" or "WHERE" will flag safe internal constants alongside dangerous user-input patterns. Teams manage PMD false positives by configuring rule thresholds, suppressing specific rule violations with @SuppressWarnings("PMD.RuleName") annotations, or excluding rules that produce too much noise for their codebase. This suppression accumulates over time and becomes its own maintenance burden.
Semgrep reduces false positives through multiple mechanisms. Taint-tracking analysis reduces false positives by understanding data origins - Semgrep only flags when the data reaching a dangerous sink is actually user-controlled. A string concatenation in a SQL query with a hardcoded internal constant does not trigger Semgrep's SQL injection rule because the taint analysis shows the concatenated value is not user-controlled. At the paid tier, Semgrep Assistant applies AI classification to findings, assesses exploitability in the context of the full codebase, and provides confidence ratings that help teams prioritize. Semgrep reports that Assistant reduces false positive noise by 20-40% out of the box. The combination of taint-aware analysis and AI triage produces a substantially lower ratio of false positives to true positives compared to pattern-only tools.
CI/CD Integration
Both tools integrate into Java CI/CD pipelines, but the integration model differs significantly.
PMD integrates natively into Maven and Gradle. The maven-pmd-plugin is the standard Java build integration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.23.0</version>
<configuration>
<rulesets>
<ruleset>rulesets/java/quickstart.xml</ruleset>
<ruleset>${project.basedir}/custom-rules.xml</ruleset>
</rulesets>
<failOnViolation>true</failOnViolation>
<printFailingErrors>true</printFailingErrors>
</configuration>
<executions>
<execution>
<goals><goal>check</goal></goals>
</execution>
</executions>
</plugin>
This runs PMD as part of mvn verify or any goal that includes the verify phase. Violations break the build immediately with the same feedback developers see for compilation errors. For GitHub Actions, GitLab CI, Jenkins, or any other CI system that runs Maven, PMD requires zero additional configuration beyond what is already in the pom.xml.
Semgrep integrates into CI/CD as a separate analysis step. For GitHub Actions:
- uses: semgrep/semgrep-action@v1
with:
config: >-
p/java
p/spring
p/owasp-top-ten
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
For GitLab, Jenkins, CircleCI, and other CI systems, Semgrep provides a Docker image and CLI that run in any environment. Diff-aware scanning means Semgrep analyzes only changed files on PRs, keeping scan times manageable even on large Java codebases. The cloud platform adds PR comment posting with inline code annotations, a centralized findings dashboard, and policy enforcement that can block PRs with critical security findings.
One practical distinction: PMD runs inside the build, so findings appear in the build log alongside compilation output. Semgrep runs as a separate CI step, so findings appear in the CI pipeline alongside other quality gates. Both approaches work well, but the build-integrated feedback of PMD feels more immediate during active development, while Semgrep's separate pipeline step provides cleaner security-specific reporting.
Java Framework and Library Coverage
Real Java security vulnerabilities appear at the interaction between application code and the frameworks and libraries those applications use. Generic pattern matching is far less effective than framework-aware analysis.
PMD's Java rules are largely framework-agnostic. PMD's extensive Java ruleset covers the Java language and standard library - unused imports, empty catch blocks, naming conventions, complexity metrics, standard library misuse. It does not have dedicated Spring Boot rules, Jakarta EE rules, or Hibernate rules that understand the security semantics of those frameworks.
Semgrep's Java rules include framework-specific coverage. Spring Security rules understand that http.csrf().disable() in a Spring Security configuration is a security issue. Hibernate rules understand that session.createQuery() with string concatenation is more dangerous than session.createQuery() with named parameters. Jakarta EE rules understand the security context of servlet lifecycle methods. This framework awareness is what makes Semgrep effective for Java web application security - the vulnerabilities that matter in production Spring Boot applications require knowing what Spring's API actually does.
Pricing Comparison
PMD Pricing
PMD is completely free. There is no paid edition, no premium features, no usage limits, and no account required. PMD is maintained as an open-source project under the BSD 4-clause license (tool) and Apache License 2.0 (rules). Integration with Maven and Gradle is via official plugins that are also free. The total cost of PMD is zero - for any team size, any codebase size, and any commercial usage.
The only "cost" of PMD is developer time: configuring rulesets, managing false positive suppression annotations, building HTML reports, and maintaining any custom XPath rules. These costs are real but fixed - they do not scale with team size.
Semgrep Pricing
| Tier | Price | What You Get |
|---|---|---|
| Community Edition (OSS) | Free | Open-source engine, 2,800+ community rules, single-file analysis, CLI and CI/CD, no login required |
| Team | $35/contributor/month (free for first 10 contributors) | Cross-file taint analysis, 20,000+ Pro rules, Semgrep Assistant (AI triage), Semgrep Supply Chain (SCA with reachability), Semgrep Secrets, centralized dashboard |
| Enterprise | Custom | Everything in Team plus SSO/SAML, custom deployment, advanced compliance reporting, dedicated support, SLA guarantees |
For full details on Semgrep's pricing tiers and what each includes, see our Semgrep pricing guide.
Cost Comparison at Different Team Sizes
| Team Size | PMD | Semgrep Community | Semgrep Team |
|---|---|---|---|
| 1-5 developers | $0 | $0 | $0 (free for 10 contributors) |
| 10 developers | $0 | $0 | $0 (free for 10 contributors) |
| 20 developers | $0 | $0 | $7,000/year |
| 50 developers | $0 | $0 | $21,000/year |
| 100 developers | $0 | $0 | $42,000/year |
For Java teams under 10 contributors, both PMD and the full Semgrep Team platform cost zero. This means there is no cost argument for choosing only one - small Java teams can run PMD for code quality and the full Semgrep platform for security SAST at no cost. For teams beyond 10 contributors where Semgrep's paid tier applies, the $35/contributor/month cost should be weighed against the security value of cross-file taint tracking, AI-powered triage, and SCA with reachability analysis.
Alternatives to Consider
If neither Semgrep nor PMD alone meets your needs, several alternatives and complementary tools are worth evaluating for Java static analysis.
SonarQube is the most comprehensive free Java code quality and security platform. SonarQube's Community Build is free and self-hosted, covering Java code quality with 600+ rules alongside security scanning, code coverage integration, duplication detection, and quality gate enforcement. SonarQube runs its own Java analyzer (not PMD internally) and adds a centralized web dashboard that PMD lacks. For teams that want both code quality metrics and security scanning in one platform with a web UI, SonarQube Community Build is the strongest free option. See our SonarQube vs PMD comparison and Semgrep vs SonarQube comparison for detailed breakdowns.
Checkmarx is an enterprise SAST platform with deep Java support and cross-file taint tracking. Checkmarx One covers Java web applications with comprehensive dataflow analysis, compliance reporting, and developer IDE integration. It is positioned for larger enterprise Java teams with compliance requirements (PCI-DSS, HIPAA, SOC 2) that require formal security audit trails. Pricing is enterprise (contact for quote). See our Semgrep vs Checkmarx comparison for a detailed breakdown.
SpotBugs with FindSecBugs is the standard Java bytecode-level security scanner. SpotBugs analyzes compiled Java bytecode (not source code) and catches a different class of security vulnerabilities - concurrency issues, null pointer defects, resource leaks, and bytecode-level injection patterns that source analysis misses. FindSecBugs extends SpotBugs with 100+ Java security rules covering OWASP Top 10 categories. Running SpotBugs with FindSecBugs alongside Semgrep provides complementary coverage: source-level taint tracking from Semgrep plus bytecode-level bug detection from SpotBugs.
Codacy is a code quality and security platform that embeds PMD, SpotBugs, and Checkstyle as its Java analysis engines alongside its own rules, presenting all findings in a unified cloud dashboard with quality gate enforcement. At $15/user/month, Codacy provides the PMD-plus-dashboard experience without managing SonarQube server infrastructure. For teams that want PMD's Java rules with a hosted platform, PR decoration, and trend reporting, Codacy is the natural upgrade path from raw PMD.
CodeAnt AI is a newer platform at $24-40/user/month that combines AI-powered code review, SAST, secrets detection, and DORA metrics in a single tool. For Java teams that want to consolidate code review and security scanning into one vendor - and reduce the number of CI steps to manage - CodeAnt AI provides a bundled alternative to running PMD, Semgrep, and a code review tool separately. It is not as deep as Semgrep for custom security rules or as mature as PMD for Java code quality, but for teams prioritizing tool consolidation with AI-powered PR review, it reduces operational overhead significantly.
For a broader view of the Java static analysis landscape, see our best SAST tools comparison and our Checkmarx vs Veracode comparison for enterprise SAST context.
Use Cases - When to Choose Each
When PMD Is the Right Choice
Java teams enforcing code quality standards. PMD's primary strength is enforcing consistent Java code quality across a team - naming conventions, complexity limits, documentation requirements, and specific anti-patterns like empty catch blocks or clone() without calling super.clone(). If your primary need is ensuring developers follow agreed-upon Java coding standards, PMD is purpose-built for this with hundreds of configurable rules.
Salesforce Apex development. PMD has one of the best Apex static analysis rule sets available in any open-source tool. For Salesforce development teams that write Apex code, PMD's Apex rules cover SOQL injection, security enforcement issues, and Apex-specific best practices. This is a PMD specialization that Semgrep does not match in rule depth for Apex.
Maven-first Java shops that want build-integrated analysis. If your Java project uses Maven as its primary build tool and your team has a culture of fixing all build-breaking issues before committing, PMD's maven-pmd-plugin integration provides the tightest possible feedback loop. Violations break the build at the same point as compilation failures, keeping code quality enforcement embedded in the existing development workflow without additional tooling.
Teams that need Java code metrics. PMD's complexity metrics (cyclomatic complexity, NPath complexity, cognitive complexity via the newer rules) and design rules (God Class, excessive coupling) provide structural code quality measurement beyond security. Teams doing technical debt analysis, prioritizing refactoring work, or enforcing architecture fitness functions in their build can use PMD's metric rules for this purpose.
Zero-budget Java security checklist items. PMD's Security rules, though limited, catch some obvious Java security anti-patterns at zero cost. For organizations with no security tooling budget at all, PMD provides baseline Java security pattern checking as part of an existing PMD setup with no additional cost or configuration. It is not a replacement for Semgrep's SAST but is better than nothing.
When Semgrep Is the Right Choice
Java web applications that take user input. If your Java application - Spring Boot REST API, Spring MVC web app, Jakarta EE application, Micronaut service - receives input from users or external systems and processes it through multiple layers before database access, file I/O, or system calls, you need cross-file taint tracking. Semgrep's Pro engine is the tool for this. PMD will miss the injection vulnerabilities in the service and data access layers by design.
Teams enforcing custom Java security policies. If your organization has internal security standards - all JDBC connections must use the approved connection pool, all file access must go through the AuditedFileService, all external HTTP calls must use the organization's HttpClientFactory with certificate pinning - Semgrep's YAML rule authoring lets you encode these policies in hours. These requirements are impossible to enforce with PMD without writing Java plugin code.
Multi-language teams. If your engineering team writes Java microservices alongside Python scripts, JavaScript frontends, Go utilities, and Terraform infrastructure, Semgrep scans all of these with a single tool, a single rule language, and a single centralized dashboard. Running separate tools for each language (PMD for Java, Bandit for Python, ESLint for JavaScript, a separate Terraform scanner) multiplies the operational overhead. Semgrep's multi-language engine reduces this to one tool.
Teams that need SCA with reachability. Semgrep Supply Chain (in the Pro tier) performs software composition analysis on Java dependencies - detecting CVEs in Maven dependencies - and adds reachability analysis to determine whether the vulnerable code path is actually called by your application. This eliminates the noise of being alerted to CVEs in transitive dependencies whose vulnerable functions are never invoked. PMD has no dependency scanning capability.
Teams of 10 or fewer contributors who want enterprise-grade Java SAST. The Semgrep full platform is completely free for up to 10 contributors. This means a 10-person Java team can have cross-file taint analysis, AI-powered triage, 20,000+ Pro rules, SCA with reachability, and secrets validation at no cost. There is no cost argument for not using Semgrep if your team is within the free tier.
When to Run Both Together
The strongest Java static analysis posture for most teams is running PMD and Semgrep together, because they cover different ground with minimal overlap:
PMD in the Maven or Gradle build: PMD runs as part of every build, enforcing code quality standards with zero additional CI infrastructure. Developers see PMD violations as build failures during normal development, not as a separate CI job to check. PMD catches naming violations, empty catch blocks, complexity violations, and code style issues that Semgrep does not target.
Semgrep in CI/CD as a dedicated security gate: Semgrep's deeper analysis, Spring framework rules, and cross-file taint tracking runs on every PR. It catches security vulnerabilities that require more analysis than single-file pattern matching supports, posts inline comments on PRs indicating the specific code that triggered the finding, and blocks merges when critical security findings are detected.
This layered approach matches the analysis depth to the appropriate feedback point: fast, comprehensive code quality checks at build time, and thorough security SAST at PR review time. The total cost for teams under 10 contributors is zero - PMD is always free, and the Semgrep Team platform is free for up to 10 contributors.
The Verdict
Semgrep and PMD occupy different roles in the Java static analysis ecosystem. Framing them as direct alternatives is a false comparison - they solve different problems.
PMD is the Java code quality enforcer. Every Java team should consider running PMD. Its hundreds of Java-specific rules for naming, complexity, unused code, and structural anti-patterns are battle-tested over two decades of Java development practice. PMD 7.x is actively maintained, supports Java 21, and integrates natively into Maven and Gradle builds at zero cost. For Java teams without any code quality enforcement, adding PMD is straightforward and immediately useful.
Semgrep is the Java security SAST tool. For any Java application that processes user input - which describes essentially all web applications and APIs - PMD's security coverage is insufficient by design. The structural inability to trace data flow across class and package boundaries means PMD cannot find the injection vulnerabilities that characterize production Java security incidents. Semgrep's taint tracking, Spring framework rules, and custom rule authoring fill this gap.
For solo developers and very small Java teams (1-5): Add PMD to your Maven build for code quality enforcement and add Semgrep Community Edition (or the free Semgrep Team platform, free for up to 10 contributors) to CI/CD for security SAST. Both are free. This combination provides comprehensive Java static analysis at zero cost.
For small to medium Java teams (5-20): Same as above. If you have up to 10 contributors, the full Semgrep Team platform is still free. If you exceed 10 contributors and need the Pro engine's cross-file taint tracking for a Java web application, Semgrep Team at $35/contributor/month is the right security investment. Compare this cost against the risk profile of a SQL injection or command injection vulnerability in a production Java application.
For larger teams or those evaluating consolidated platforms: Consider SonarQube as the platform that unifies code quality (PMD's domain) and security (Semgrep's domain) into a single tool with a centralized dashboard and quality gate enforcement. Or evaluate CodeAnt AI at $24-40/user/month for teams that want AI-powered code review combined with SAST and code quality analysis in one platform. See our Semgrep vs SonarQube comparison and best SAST tools guide for broader context.
The bottom line: run PMD for Java code quality enforcement. Run Semgrep for Java security SAST. For teams under 10 contributors, both are completely free - there is no reason to choose one over the other.
Further Reading
- Codacy vs Checkmarx: Developer Code Quality vs Enterprise AppSec in 2026
- Codacy vs Semgrep: Unified Platform vs Composable Security Engine (2026)
- DeepSource vs Coverity: Static Analysis Platforms Compared (2026)
- DeepSource vs Semgrep: Static Analysis Tools Compared (2026)
- Semgrep vs Bandit: Python Security Scanning Compared (2026)
Frequently Asked Questions
Can Semgrep replace PMD for Java projects?
Semgrep can replace most of what PMD does for security-related Java analysis and goes significantly further with cross-file taint tracking. However, PMD covers Java code quality concerns that Semgrep does not target by design - naming convention enforcement, cyclomatic complexity limits, unused variable detection, and God Class detection. If your primary need is security SAST with some code quality checks, Semgrep handles this well. If your primary need is enforcing Java code style, naming conventions, and structural quality metrics, PMD remains the purpose-built tool. Many Java teams run both: PMD for code quality in the Maven or Gradle build, and Semgrep for security SAST in CI/CD. They are complementary rather than directly competing.
Does PMD detect security vulnerabilities in Java?
PMD has limited security detection through rules in its Security category and through community rulesets like the OWASP P3C rules. It can flag patterns like hardcoded IVs, use of System.exit in library code, and some injection-prone string patterns. However, PMD performs single-file, pattern-based analysis and cannot trace data flow across method calls and class boundaries. This means PMD structurally cannot detect injection vulnerabilities like SQL injection or XSS in well-architected Java applications where user input flows from a controller through a service layer to a data access object. For Java security analysis, teams pair PMD with Semgrep (for SAST with taint tracking), SpotBugs with FindSecBugs (for bytecode-level security), or a dedicated SAST platform like Checkmarx.
Is Semgrep good for Java?
Yes. Semgrep has strong Java support including taint-tracking rules for common Java web vulnerabilities, framework-specific rules for Spring Boot, Spring MVC, and Jakarta EE, and OWASP Top 10 coverage for Java applications. The community registry includes hundreds of Java-specific rules covering SQL injection, XSS, command injection, deserialization vulnerabilities, and insecure cryptography. Semgrep's Pro engine performs cross-file dataflow analysis for Java, tracing user input from Spring controller methods through service layers to JDBC calls or JPA queries. Semgrep also understands Java-specific frameworks and detects misuse of common Java libraries. For Java SAST specifically, Semgrep is one of the strongest tools in the ecosystem alongside Checkmarx and Fortify.
What languages does PMD support beyond Java?
PMD 7.x supports 16 languages: Java, Kotlin, JavaScript, TypeScript, Apex (Salesforce), Visualforce, XML, PL/SQL, PLSQL, XSL, Velocity, Swift, Groovy, JSP, Modelica, and NetLogo. The depth of support varies significantly by language - Java has the most mature and comprehensive rule set with hundreds of rules, while other languages have more limited coverage. Apex support is particularly noteworthy because PMD is one of the few open-source tools with dedicated Apex rules, making it valuable for Salesforce development teams. For multi-language stacks that span Java, JavaScript, Go, Python, and infrastructure code, Semgrep's multi-language engine provides more consistent depth across all languages than PMD.
How does Semgrep's rule system compare to PMD's ruleset XML?
Both tools use declarative rule configuration, but the systems are fundamentally different. PMD uses XML rulesets that reference built-in rule classes, configure rule properties, and define custom XPath-based rules. Writing a custom PMD rule requires either XML XPath expressions or a Java plugin that extends PMD's AST visitor framework. Semgrep uses YAML rules that pattern-match against the target language's own syntax. A Semgrep Java rule looks like Java code with metavariable placeholders, making it readable by any Java developer. Writing a Semgrep rule takes 10-20 minutes for a developer who has never used Semgrep. Writing a custom PMD XPath rule requires understanding PMD's AST structure and XPath syntax, which takes significantly longer to learn. For organizations that need to encode custom security standards as rules, Semgrep's authoring experience is substantially more accessible.
Is PMD free and open source?
Yes. PMD is completely free and open source under the BSD 4-clause license and Apache License 2.0 (rules). There is no paid tier, no premium features, no usage limits, and no account required. PMD integrates as a Maven plugin (maven-pmd-plugin), Gradle plugin, Ant task, and standalone CLI. The total cost of PMD is zero dollars for any team size, any codebase size, and any commercial usage. Semgrep's Community Edition is also free and open source under LGPL-2.1, but the full Semgrep platform with cross-file taint analysis, AI triage, and 20,000+ Pro rules costs $35/contributor/month beyond the first 10 contributors.
Can I run Semgrep and PMD together in CI/CD?
Yes, and running both is a common and well-justified pattern for Java teams. PMD runs inside the Maven or Gradle build lifecycle (via maven-pmd-plugin or the Gradle PMD plugin), catching code quality issues - naming violations, complexity, unused code, and structural anti-patterns - as part of every build. Semgrep runs as a separate step in CI/CD, adding security SAST with taint tracking, framework-specific vulnerability rules, and custom organization security checks. The two tools have minimal overlap: PMD focuses on Java code quality, Semgrep focuses on security. Adding Semgrep to a pipeline that already has PMD takes under 10 minutes and provides substantially better security coverage than PMD alone.
Does Semgrep support Spring Boot security scanning?
Yes. Semgrep has dedicated Spring Boot and Spring MVC rules in its registry covering the most common Spring security anti-patterns. These include: missing @PreAuthorize or @Secured annotations on REST endpoints, unsafe use of SpEL (Spring Expression Language) with user input, CSRF protection disabled in Spring Security configuration, insecure CORS configuration, missing authentication in Spring Security filter chains, unsafe handling of Spring Actuator endpoints, and SQL injection through Spring Data JPA native queries. The Spring-specific rules are available in the community registry and expanded in the Pro rule library. Semgrep can also trace user input from @RequestParam and @PathVariable annotations through service method calls to JDBC template queries, finding injection vulnerabilities across the full Spring application stack.
What is the difference between Semgrep and SpotBugs for Java security?
Semgrep and SpotBugs analyze Java code at different levels. Semgrep analyzes Java source code using pattern matching and taint analysis, looking for code patterns that represent security vulnerabilities and quality issues. SpotBugs (and its FindSecBugs plugin) analyzes compiled Java bytecode to detect bugs that source analysis misses - including concurrency issues, resource leaks, incorrect API usage, and security vulnerabilities detectable at the bytecode level. SpotBugs with FindSecBugs is particularly strong at detecting certain vulnerability patterns in compiled code that are less visible in source. Semgrep is stronger at custom rules and cross-file dataflow tracing in source. The most thorough Java security setup uses both: Semgrep for source-level taint tracking and custom rules, SpotBugs with FindSecBugs for bytecode-level bug detection. PMD adds code quality enforcement on top of either or both.
Which Java SAST tool has the lowest false positive rate?
Among commonly used Java SAST tools, Semgrep's Pro engine with taint tracking has lower false positive rates than PMD's security rules because it understands data flow context. PMD's security rules are pattern-based and produce false positives when the flagged pattern is safe in context - for example, flagging a string that looks like a SQL query even when the interpolated variable comes from a safe internal constant. Semgrep's taint analysis distinguishes between user-controlled and internally-controlled data, only flagging when user input actually reaches a dangerous sink. At the paid tier, Semgrep Assistant further reduces false positive noise by 20-40% through AI-powered triage. That said, the tools measure different things: PMD catches more code quality false positives in security categories, while Semgrep's community rule set can have false positives from simpler rules. For lowest false positive security scanning, Semgrep Pro with taint analysis is the stronger choice.
Is PMD still maintained and worth using in 2026?
Yes. PMD remains actively maintained in 2026. PMD 7.x, released in 2024, brought a major rewrite with improved performance, a consistent new API, full Java 21 support, improved Kotlin rules, and a revamped rule configuration system. The project is maintained under the Apache License, supported by an active open-source community, and used by major Java projects and enterprises. PMD 7.x is the version to use - it resolves many of the quirks of the 6.x series and provides better integration with modern Java toolchains. For teams that need Java code quality enforcement, naming convention checking, complexity limits, and specific anti-pattern detection, PMD 7.x delivers all of this at zero cost and is worth including in any Java CI/CD pipeline.
What is the best Java static analysis tool for a small team?
For a small Java team under 10 developers, the best setup is PMD plus Semgrep Community Edition (or the full Semgrep platform, which is free for up to 10 contributors). PMD provides code quality enforcement via the Maven or Gradle build at zero cost. Semgrep's free tier adds cross-file security SAST, Spring framework rules, and AI triage. This stack delivers enterprise-grade Java static analysis at zero cost for small teams. Teams that want a single consolidated platform can consider Codacy at $15/user/month (which embeds PMD and SpotBugs behind a unified dashboard) or CodeAnt AI at $24-40/user/month for AI-powered code review combined with SAST and code quality in one tool. For Java-specific depth, Qodana (by JetBrains) at $6/contributor/month provides IntelliJ-synchronized analysis with JVM-specific rules.
Originally published at aicodereview.cc

Top comments (0)