SYSTEM Cited by 1 source
PMD static analyzer¶
PMD (pmd.github.io) is a long- standing OSS static analyzer for Java and other languages (Apex, JavaScript, JSP, XML, Visualforce). It operates over an Abstract Syntax Tree (AST) of source code and ships with a large catalog of pre-built rules covering style, performance, and correctness issues. PMD rules are commonly authored as XPath expressions over the AST, with Java rule classes as the lower-level alternative.
This page is a stub created for cross-referencing from sources/2026-05-08-netflix-scaling-archunit-with-nebula-archrules, where PMD is named as the comparison foil for why Netflix chose ArchUnit for its rule-distribution substrate.
Why Netflix chose ArchUnit over PMD (per the post)¶
Three structural axes named in the source:
1. AST vs bytecode (the core technical choice)¶
"Some tools, such as PMD, process rules against an AST (abstract syntax tree). An AST is a structured representation of source code. This kind of tool will have rules that are syntax dependent. Rules that need to support multiple JVM languages, such as Kotlin or Scala, often need to be rewritten for each language. It also allows code which should be found to be hidden under syntactic sugar not anticipated by the rule author." — sources/2026-05-08-netflix-scaling-archunit-with-nebula-archrules
See concepts/bytecode-vs-ast-static-analysis for the canonical wiki framing of this tradeoff.
2. Rule-authoring ergonomics¶
"Tools like PMD and Spotbugs are not optimized for custom rule authorships. Most usage of these tools run built-in provided rules, or add in pre-made third party plugins."
"Take a look at what a custom rule for PMD might look like:
//AllocationExpression/ClassOrInterfaceType[ @Image='DateTime' and ( (count(..//Name[@Image='DateTimeZone.UTC'])<=0) and (count(..//Name[@Image='DateTimeZone.forID'])<=0) ) or ( ( (count(..//Name[@Image='DateTimeZone.UTC'])>0) or (count(..//Name[@Image='DateTimeZone.forID'])>0) ) and (../Arguments/ArgumentList and count(../Arguments/ArgumentList/Expression) = 1) ) ]"This rule ensures that DateTimes are not instantiated without an explicit zone. This is a raw string meant to be used within PMD's xpath parser. There is no IDE guidance on crafting it. To test it, a whole separate PMD process needs to be wired up to interpret the rule and evaluate it against a source file." — sources/2026-05-08-netflix-scaling-archunit-with-nebula-archrules
The Netflix post is partially polemical here — PMD does have a Java rule API in addition to XPath — but the central point about XPath-as-CDATA-strings vs type-safe builder API holds for the XPath path.
3. Class-graph retention¶
PMD's per-file AST model can't naturally express cross-class rules ("no class outside this package may call into the Deprecated members of this class"). ArchUnit's classpath-graph model can. This isn't unique to PMD — most AST-based tools share this limitation — but the post names it as a third structural advantage of ArchUnit.
Where PMD still fits¶
The post doesn't entirely dismiss PMD; the framing is "appropriate for different problem shapes." PMD is well-suited to:
- Style and convention rules that operate on source formatting (which bytecode loses) — e.g. "variable names must be camelCase," "don't use tabs for indentation."
- Single-language deployments where cross-language rule reuse isn't a goal.
- Per-file rules where the class graph isn't relevant.
Adjacent tools¶
- SpotBugs — bytecode-based JVM static analyzer; older cousin of PMD with bytecode-level analysis but less ergonomic rule authoring than ArchUnit.
- Checkstyle — convention/style enforcement; AST-based.
- Error Prone — Google-built compile-time error detector using javac plugin API, AST-based but with much richer cross-reference support than PMD.
- SonarQube — meta-platform that integrates many of the above plus its own rule engine.
Seen in¶
- sources/2026-05-08-netflix-scaling-archunit-with-nebula-archrules — Netflix names PMD as the comparison foil illustrating why ArchUnit's bytecode + builder-API + class-graph approach was chosen.
Related¶
- systems/archunit — the comparison winner for Netflix's use case.
- systems/asm-bytecode-toolkit — the bytecode framework underlying ArchUnit's alternative approach.
- concepts/bytecode-vs-ast-static-analysis — the structural tradeoff.