JEP 190: Pluggable Static Analyzers
|Authors||Eric McCorkle, Brian Goetz|
|Component||tools / javac|
|Discussion||compiler dash dev at openjdk dot java dot net|
|Endorsed by||Brian Goetz|
Explore the design space for implementing a framework for pluggable
static type analyzers for
javac. This framework, in conjunction with
the type annotations provided by JSR 308 (JEP 104), will allow
users to define extensions that can perform arbitrary static analysis at
compile time. The eventual goal of this effort is to provide a common
framework for implementing code analysis tools; however, the goal of this
phase is to explore the design space and gain knowledge and experience.
This is a research JEP. The sole goal of this JEP is to explore the design space sufficiently to be able to propose a feature JEP (or recommend that the feature not be pursued.)
The goals can be stated as follows:
Gather and analyze requirements for static analyzers and a framework to support them.
Implement a handful of static analyzers both as a proof-of-feasibility and to serve as an example.
This is not a transform or optimization framework; static analyzers should not modify the program.
We should not implement a large number of static analyzers ourselves, as part of this effort, beyond what is necessary to evaluate and understand the engineering concerns, and to provide a small set of examples, and to provide the community with the tools to convert existing analysis implementations into the framework.
It is not a goal of this JEP to produce a production-ready implementation or specification.
This research JEP will be judged successful if: it produces a design that we wish to move forward to a feature JEP, OR certainty that we do not wish to proceed with this feature.
This effort benefits the Java language ecosystem in several ways. First, it provides a foundation upon which we can build static analysis tools for improving the quality of the JDK. Furthermore, it will likely generate a renewed interest in extensions to the Java type system, both in industry as well as academic research. Most importantly, however, it will enable teams of developers to configure and build analysis tools that more effectively enforce their coding standards, and which more effectively detect errors common to their specific applications.
A simple example of what could be done with the proposed framework is an extension of the core type system which emits warnings for a collection of anti-patterns known to be problematic, such as mutable static fields (likely security risk), reference comparisons (likely an error), and overriding equals without overriding hashCode (a performance problem).
However, the possible applications are more far-reaching. Tools such as FindBugs, lint, and other such tools could be reimplemented as pluggable analyzers and used as part of a build cycle. The proposed framework, combined with type annotations, also opens the door to more powerful error-detection and verification techniques, such as model-checking and formal specifications.
The proposed framework also can be adapted to work in a similar way with bytecode, providing many of the same benefits.
Users should be able to define a compilation configuration, which consists of a set of selected inspections and configuration data for those inspections. (For example, the user may wish to customize the mapping to diagnostic levels, so some inspections become warnings, some errors, etc.)
An inspection plugin should be packagable on a fine-grained basis, and inspections should be able to request access to source, bytecode, tree, and classpath data, as well as emit diagnostic information that is merged into the diagnostic output of compilation. It should be easy for maintainers of existing inspection tools (such as FindBugs) to repackage their inspections individually as plugins.
There are several frameworks that have been produced in the course of
academic work. Many do not represent production-ready products, and
neither were they developed to interface cleanly with
javac. There are
also production-ready standalone tools (most notably FindBugs), which are
used in commercial software development. However, they are currently
separate from the
javac tool chain. As such, they must be run as
separate tools, integrating them into a build/test system is nontrivial,
and there is no easy way to pick specific features from multiple
The ASM framework is a bytecode analysis and rewriting framework. However, it lacks the ability to analyze java source and it lacks certain features that are critical for certain kinds of analysis.