Files
javademos/classfile-api/README.md
T

29 lines
2.4 KiB
Markdown

# classfile-api
Companion code for the ankurm.com article **The Java ClassFile API (JEP 484): Read, Generate and Transform Bytecode Without ASM**
(https://ankurm.com/java-classfile-api-jep-484/).
`java.lang.classfile` was a preview API in JDK 22 and 23 (JEPs 457, 466) and is **final since JDK 24 (JEP 484)**: no `--enable-preview`.
Everything here ran on Temurin 25.0.5+8; the API diff also ran on Temurin 24.0.2 and 26.0.2.1. The only dependency is ASM 9.11.1, used by the comparison classes.
| File | What it shows | Output |
|---|---|---|
| `Target.java`, `Timings.java` | the class we inspect/instrument, and the sink the injected code calls | |
| `ParseDemo.java` | `ClassFile.of().parse`, `ClassModel` traversal, pattern-matching over elements and instructions | `output/01-parse.txt` |
| `GenerateDemo.java` | `ClassFile.build`, `verify`, `Lookup.defineClass` vs `defineHiddenClass` | `output/02-generate.txt`, `03-javap-generated.txt` |
| `BrokenGenerate.java` | dropped stack maps, wrong return type, stack underflow, swapped exception-table labels | `output/04-broken-generate.txt` |
| `TimingTransform.java`, `TransformDemo.java` | `ClassTransform` / `MethodTransform` / `CodeTransform` inserting timing; naive vs exception-safe | `output/05-transform.txt`, `06-javap-instrumented.txt` |
| `AsmParse.java`, `AsmGenerate.java`, `AsmInstrument.java`, `AsmGotcha.java` | the same three jobs in ASM 9.11.1, asserted equal; plus the `EXPAND_FRAMES` trap | `output/08`, `09`, `10`, `15` |
| `VersionLimits.java` | a newer class file than the reader knows: `java.lang.classfile` vs ASM | `output/11-version-limits.txt` |
| `Bench.java` | indicative parse and copy timing on 2000 `java.base` classes (thread CPU time, noisy) | `output/13-bench.txt` |
| `scripts/run-all.sh` | API diff of `java.lang.classfile` across JDK 24, 25, 26 | `output/07-api-diff-24-25-26.txt` |
| `scripts/spring-core-probe.sh` | what `spring-core` 7.0.10 ships for the ClassFile API | `output/14-spring-core-probe.txt` |
```bash
JDK25=/path/to/jdk-25 JDK24=/path/to/jdk-24 JDK26=/path/to/jdk-26 ./scripts/run-all.sh # JDK24/JDK26 optional; needs Maven for the ASM jars
JDK25=/path/to/jdk-25 ./scripts/spring-core-probe.sh
```
The demos assert as they go (`PASS`/`FAIL`, non-zero exit on failure), like the other standalone modules; there is no JUnit. Output is byte-stable except `13-bench.txt`.
Not reproduced: nothing was run on JDK 22/23 previews.