New JEP: Classfile Processing API
brian.goetz at oracle.com
Sun Jun 19 14:11:38 UTC 2022
Generation, parsing, and transformation of classfiles is ubiquitous in
the Java ecosystem. Frameworks transform classfiles on the fly by
hooking into classloaders or using `java.lang.instrument`; compilers and
IDEs for all sorts of languages read and write classfiles; static
analysis tools read classfiles; migration tools transform classfiles.
In the JDK, we have a static compiler (`javac`) and other tools
(`javap`, `jlink`) that read or transform classfiles, and numerous
platform features that operate by classfile generation (reflection,
lambdas, dynamic proxies, method handles), as well as many tests that
generate classfiles. In fact, the JDK contains at least three libraries
for processing classfiles: an internal one (used by JDK tools such as
`javac`); a fork of ASM (used by lambdas and many other platform
features), and a fork of BCEL (contained inside a fork of Xalan). And of
course the ecosystem has many such libraries: ASM, javassist, cglib,
BCEL, gnu.bytecode, ByteBuddy, and many others.
Over the years, there have been many calls for Java to have an
"official" classfile library, and there are numerous practical reasons
to create one, and the shift to the six-month cadence has added two new
reasons. Firstly, tools that bundle classfile libraries are more likely
to encounter classfile versions "from the future", because they use a
classfile library that knows about Java N, but the customer may be
running it on Java N+1, which was released only six months later.
Second, the pace of classfile format evolution has picked up
significantly in recent years, with a significant fraction of releases
having at least some change to the classfile format (new attributes, new
constant pool forms, new bytecodes, new combinations of flags, etc).
Having an official classfile library would mean that applications and
tools are guaranteed to have access to a library that is up-to-date to
the latest classfile version that will run on the current JDK.
It might seem an "obvious" choice to "just" standardize on ASM, but
there are many reasons not to do so. ASM is an old codebase with plenty
of legacy baggage; the design priorities that informed its architecture
are not ideal for the JDK in 2022; and the language has improved
substantially since them (lambdas, records and sealed classes, pattern
matching.) What were the best possible API idioms in 2002 (visitors)
may not be ideal two decades later.
A draft JEP can be found here:
Such an API will have many consumers, both internal to the JDK and
external: compilers, analysis tools, platform implementation, 3rd party
libraries, tests, etc. We will focus initially on the internal JDK
consumers, incrementally migrating them off of the existing libraries
and onto the new library. Eventually, once all the internal consumers
are migrated, we will be able to remove ASM from the JDK entirely.
Initially, the library will be internal-only (non-exported), to gain
experience with and refine the API before committing to a public
version. When the API is sufficiently stable, it will be exported for
public use, first as a preview API and eventually as a permanent API.
Comments on the JEP itself -- the concept, motivation, and design goals
-- are invited for discussion. The JEP includes some code examples,
which are hopefully illustrative, but I will request that people hold
off on API discussions for the time being, to make room for discussion
on the JEP itself first.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the discuss