A static analysis tool that builds class hierarchies and call graphs from Java bytecode. It parses JAR files using the ASM library, identifies all possible call targets for each polymorphic call site via Class Hierarchy Analysis (CHA), and renders the results as DOT graphs for visualization with Graphviz.
- Class Hierarchy Analysis (CHA): Builds a complete type hierarchy including superclasses, interfaces, and subtypes.
- Call Graph Construction: Identifies method invocations and resolves virtual/interface calls to all possible runtime targets.
- Polymorphism Resolution: Uses BFS traversal through the class hierarchy to find all possible implementations of virtual and interface calls.
- DOT Visualization: Generates Graphviz-compatible
.dotfiles with color-coded edges and styled nodes for classes, methods, and call relationships.
The bundled pacman.jar (in src/test/resources/) contains a simple Pac-Man game with polymorphic classes (Sprite, Pacman, Ghost, World, etc.). Running the analyzer on it produces the following static call graph:
What you can see:
- Class hierarchy:
PacmanandGhostboth implement theSpriteinterface;MagicWorldandNormalWorldextend the abstractWorldclass. - Polymorphic resolution: A call to
Sprite.step()fans out to bothPacman.step()andGhost.step()as possible targets. - Edge styles: Dashed edges represent virtual calls, dotted edges represent interface calls, and solid edges represent special calls (constructors,
super).
- JAR Scanning: The
ArchiveScannerwalks through a JAR file and loads each.classfile using ASM'sClassNode. - Hierarchy Construction: The
ClassHierarchyBuilderrecords superclass relationships, implemented interfaces, subtypes, and declared methods for each class. - Call Graph Analysis: The
CallGraphClassHierarchyAnalyzerexamines bytecode instructions (INVOKEVIRTUAL,INVOKESPECIAL,INVOKEINTERFACE) and resolves possible call targets through the hierarchy. - Rendering: The
CallGraphRendereroutputs a DOT graph with:- Class nodes styled by kind (solid = concrete, dashed = abstract, dotted = interface)
- Hierarchy edges (solid arrows to superclasses, dotted to interfaces)
- Call edges (dashed for virtual, dotted for interface, solid for special) with color coding (blue = declared target, brown = CHA-resolved target)
- Java 21 or higher
- Graphviz (optional, required for PDF rendering)
- Gradle (included wrapper)
Run the included example using the bundled Pac-Man JAR:
./run.shThis will:
- Build the project
- Analyze
src/test/resources/pacman.jar - Generate
out/callgraph.dot - Convert to PDF:
out/callgraph.pdf(requires Graphviz)
You can also pass a custom JAR file:
./run.sh /path/to/your.jar./gradlew run --args "'/path/to/input.jar' '/path/to/output_dir'"./gradlew build
java -cp build/libs/*.jar:lib/asm-9.7.jar:lib/asm-tree-9.7.jar:lib/asm-util-9.7.jar \
lab.App /path/to/input.jar /path/to/output_dirThe tool generates a callgraph.dot file in the specified output directory. Convert it to a visual format with Graphviz:
dot -Tpdf -o callgraph.pdf callgraph.dot
dot -Tpng -o callgraph.png callgraph.dotVisual legend:
| Element | Meaning |
|---|---|
| Solid box | Concrete class |
| Dashed box | Abstract class |
| Dotted box | Interface |
| Solid arrow (tan) | Extends superclass |
| Dotted arrow (tan) | Implements interface |
| Blue call edge | Declared call target |
| Brown call edge | CHA-resolved possible target |
.
├── run.sh # Quick-start script
├── build.gradle # Gradle build configuration
├── src/
│ ├── main/java/lab/
│ │ ├── App.java # Main entry point
│ │ ├── framework/
│ │ │ ├── ArchiveScanner.java # JAR file traversal
│ │ │ └── ClassAnalyzer.java # Analysis pass interface
│ │ ├── hierarchy/
│ │ │ ├── ClassHierarchy.java # Type registry
│ │ │ ├── ClassHierarchyBuilder.java # Builds hierarchy from bytecode
│ │ │ └── type/ # Type representations
│ │ └── callgraph/
│ │ ├── CallGraphClassHierarchyAnalyzer.java # CHA-based call analysis
│ │ ├── CallGraphRenderer.java # DOT graph generation
│ │ ├── CallSite.java # Method invocation model
│ │ └── Method.java # Method declaration model
│ └── test/
│ ├── java/lab/
│ │ ├── PacmanCallGraphTest.java # Call graph tests
│ │ └── PacmanClassHierarchyTest.java # Hierarchy tests
│ └── resources/
│ └── pacman.jar # Test JAR (Pac-Man game)
└── gradlew # Gradle wrapper
This project is open source and available for personal and educational use.
