Answer
Yes – @CompileStatic should be applied only to Groovy classes that can be proven free of dynamic metaprogramming (methodMissing, propertyMissing, categories, Expando). Package‑level annotation is not enough; per‑class (or per‑method) granularity is required to keep dynamic escape hatches where they are needed.
Confirmed facts
- @CompileStatic is an AST transformation that generates Java bytecode with static type checking, eliminating Groovy’s meta‑class dispatch.
- For low‑traffic workloads the CPU savings are usually modest; the main gain comes from reduced startup and per‑request latency.
- Any class annotated with @CompileStatic cannot use dynamic features; attempting to do so yields a compilation error or runtime NoSuchMethodError.
Steps for this case
- Identify candidate classes: POJOs, utility or service classes that use explicit typing and do not reference def, methodMissing, propertyMissing, categories, or ExpandoMetaClass.
- Add @groovy.transform.CompileStatic to the class header (or to specific methods if only part of the class needs static compilation).
- Recompile the project; the build will fail if any incompatible dynamic construct is present.
- Run the full test suite to catch any hidden dynamic calls that survived compilation.
Analysis and verification
To automate candidate selection, run a static inspection that flags:
- Variable or parameter types declared as def or Object without casting.
- Calls to methodMissing, propertyMissing, or use of GroovyCategories.
- References to ExpandoMetaClass.
Many IDEs (IntelliJ IDEA, Eclipse Groovy) provide inspections for dynamic call or unsafe type. A simple Gradle task can run the Groovy compiler with -XstaticCompile to report incompatibilities.
Measure the impact with a scoped benchmark, for example:
long start = System.nanoTime();
service.handleRequest();
long end = System.nanoTime();
println 'Request time: ' + (end - start) + ' ns';
Missing diagnostic detail: Does the codebase use Groovy Categories or ExpandoMetaClass for cross‑cutting concerns? If yes, those specific classes must remain dynamic, as static compilation will ignore those runtime extensions.