A tool to inspect and analyze HotSpot AOTCache (.aot) files.
The format is adapted for JDK 27+7 but also works well for JDK 25.
Note that the value of access_flags is different and incorrect in JDK 25-created AOTCache files due to 8372098: Move AccessFlags to InstanceKlass.
mvn packagejava -jar aotp/target/aotp-0.0.1-SNAPSHOT.jar <cache.aot> --headerjava -jar aotp/target/aotp-0.0.1-SNAPSHOT.jar <cache.aot> --list-classesFor example, list classes that have had their <clinit> pre-executed:
java -jar aotp/target/aotp-0.0.1-SNAPSHOT.jar <cache.aot> --list-classes=aotClassFlags:has_aot_initialized_mirrorMultiple flags can be required (all must match):
java -jar aotp/target/aotp-0.0.1-SNAPSHOT.jar <cache.aot> --list-classes=aotClassFlags:has_aot_initialized_mirror,has_archived_enum_objsjava -jar aotp/target/aotp-0.0.1-SNAPSHOT.jar <cache.aot> --print-class "java/lang/String"Caution
This may be wrong. See #9.
java -jar aotp/target/aotp-0.0.1-SNAPSHOT.jar <cache.aot> --class-size "java/lang/String" "java/lang/Object"Print all constant pools:
java -jar aotp/target/aotp-0.0.1-SNAPSHOT.jar <cache.aot> --list-constant-poolsPrint one class's constant pool:
java -jar aotp/target/aotp-0.0.1-SNAPSHOT.jar <cache.aot> --list-constant-pools="org/apache/pdfbox/tools/TextToPDF"Verify that an AOT cache was built from a specific set of JARs. Detects version mismatches (stale cache after a dependency upgrade) and tampered caches (injected symbols).
java -jar aotp/target/aotp-0.0.1-SNAPSHOT.jar <cache.aot> --check-integrity lib1.jar lib2.jar ...The report has three sections:
- matched — classes present in both the JARs and the AOT cache with identical constant pool symbols
- mismatched — classes whose constant pool differs; each entry shows
missingSymbols(in JAR but absent from AOT) andaddedSymbols(in AOT but absent from JAR, indicating injection or a version change) - stale — application classes in the AOT cache with no corresponding class in the supplied JARs
The check uses constant pool Utf8 entries (method/field names, type descriptors, string literals) as the comparison unit. If a method signature or class reference changed, the descriptor Utf8 changes and is caught here.