Open-source project
Adrninistrator/java-all-call-graph avatar
Adrninistrator/java-all-call-graph

java-all-call-graph: a Java static analyser that ends in SQL

Generate all call graph for Java Code.

573 stars137 forksJavaApache-2.0

At a glance

What is it?
java-all-call-graph parses compiled Java code with a bytecode library, writes what it finds into a relational database, and then lets you query the result with SQL or walk it as a call graph. It goes further than method edges, extracting MyBatis table names, argument values and string concatenations, and it ships an MCP and web interface in a companion server project.
Who is it for?
Adopt java-all-call-graph if your work involves impact analysis of a Java service, code slimming, precise test selection or a security scan that needs a call graph rather than a diagram, and you can accept running a two phase pipeline against your build artefacts.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 57 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Unstructured code turned into tables you can query

The stated goal of java-all-call-graph is to use Java code to perform automated static analysis on Java code, structuring the unstructured information in that code into a relational database, so it can provide useful information for the development, testing and security scenarios of a Java application.

Putting the data in a database rather than in a graph file is the decision that shapes everything else. The README says the project supports static analysis of compiled Java code with the related information written into database tables that can then be queried with SQL statements.

The analysis covers the ordinary building blocks of a Java codebase: classes, methods, fields, annotations, generics, method calls and enums. On top of that it parses information from a set of common development frameworks, naming MyBatis, Spring AOP, Spring Bean, Spring Controller and Spring Task.

So the audience is engineers who need to answer questions about a running codebase at scale rather than read it. Impact analysis when a method changes, which tests cover a given path, which tables a service touches, whether a dependency upgrade breaks anything. The data model has two named tables at the centre of it. A method call relation is a caller and a callee, described by package, class, method name, parameters and return type, along with the kind of call such as static against instance, and that relation is written to the method_call table. Method call information is the detail of a call, the constant values used for the callee or the arguments, variable types, argument positions, return values of other calls, and class fields, and that goes into the method_call_info table.

Putting method edges and method details in separate tables is what makes the SQL angle pay off, since the interesting questions are joins.

Call chains upward and downward, and the stack between them

Three related concepts build on each other, and the README defines them precisely enough to be useful.

The full call chain is generated from a given method. Downward, it starts at that method, passes through the methods it calls directly and indirectly, and ends at the methods that call nothing further. Upward, it starts at the method, passes through the methods that call it directly and indirectly, and ends at the methods that nothing calls. The chain is tree shaped, and the README gives the example:

java
com.example.Main:main(String[])
├─ com.example.service.UserService:getUserById(Long)
│   ├─ com.example.repository.UserRepository:findById(Long)
│   │   ├─ com.example.mapper.UserMapper:toEntity(ResultSet)
│   │   └─ com.example.validator.IdValidator:validate(Long)
│   └─ com.example.cache.UserCache:get(String)
└─ com.example.util.Logger:info(String)

The call stack is then defined on top of that chain. It is the path from the starting method to some particular called or calling method, and it is a linked list rather than a tree. The same example shows two such paths out of the same starting method, one through the service and repository layers to the mapper, and another through the logger.

The README is careful about the shape of the result, noting that a chain generated up or down from a method can be thought of as a subgraph of the full call graph, shaped like a tree with a root, but still a graph because cyclic calls are possible. That distinction is the one to keep in mind: a call graph with recursion is not a tree, and any tool that prints it as one is hiding the cycles that usually matter.

The library also extracts information from the generated stack file that reflects business meaning, such as the constant values used in a call, parameter types, the generic types of a method's parameters or return value, and the database table names a MyBatis operation touches.

The pipeline runs in two phases, and the second one writes the database

The main flow section describes how the pieces fit together, and it is a two phase design that explains the project structure.

First, the code is parsed and written to the database. The RunnerWriteDb class of java-all-call-graph calls the java-callgraph2 library, which reads the jar files and other artefacts that need parsing, performs the static analysis and writes the analysis results to text files. The RunnerWriteDb class then reads those generated files and writes them into the database.

The second phase is separate. The other classes of java-all-call-graph read the database and generate the data that is actually asked for, including the files for the full call chains and the call stacks.

The split has an obvious operational consequence, which the README states directly: when the analysed code changes, the first step has to be run again so the database holds data matching the latest code. So the database is a derived artefact with a refresh requirement, not a live view.

The text file intermediate is the other detail worth knowing. It means the expensive analysis stage is decoupled from the database write, so the same analysis output can be inspected before it lands in tables, and a re-run of the analysis does not require the database to be empty. It also means the pipeline is not a single process, and an operator has to know which stage produced the data they are looking at.

MyBatis table names, JarDiff and JDK compatibility scanning

The feature list runs well past call edges, and the extra capabilities are where the project distinguishes itself from a plain call graph tool.

Table name analysis is the one with the most obvious appeal. When generating a call chain or a call stack, the tool can resolve which database tables a MyBatis mapper method operates on, and the documentation is specific that this supports MySQL databases. The MyBatis mapper XML is parsed rather than the Java annotations, which is the harder half of the problem, since the table name lives in a SQL string inside an XML file.

JarDiff compares different versions of a jar file, identifies the methods that changed, and then generates the full upward or downward call chain for them, which produces the scope of impact of an upgrade. It also works from the other direction, comparing the SQL statements in MyBatis mapper XML files to find the mapper methods that changed, and then producing the call chain and impact scope from those.

The JDK and dependency compatibility scan addresses a different problem. When a Java application upgrades the JDK or a library version, the README says compatibility problems can appear where a library uses a class, method or field that cannot be found, and the tool scans for those, including checking classes whose names are entirely related.

Two smaller capabilities round it out. One retrieves the parameter types or values used in a method call, meaning the constant value of a callee or argument and the type of the argument. The other parses string concatenation, working out the content of each part before the concatenation and the resulting string value, for cases built from string constants, enum constant method call return values and similar expressions.

Taken together, these read as tooling for understanding a system you did not write and cannot change.

The dependency chain, and what it says about the design

The README publishes the dependency relationships, and they describe the architecture accurately in six lines.

java-all-call-graph depends on java-callgraph2, which is the library that performs the static analysis of Java code, and java-callgraph2 in turn depends on bcel for parsing Java bytecode information. java-all-call-graph also depends on druid as a data source, and on mybatis-mysql-table-parser, which parses the MySQL statements inside MyBatis XML, and that parser depends on druid to parse the SQL statements and jdom2 to parse the XML files. Finally, java-all-call-graph depends on java-text-to-excel to turn text into Excel files, and that library depends on fastexcel to do the actual writing.

Two things follow. The analysis is bytecode level, not source level, because the parser underneath is a bytecode library, which is why the documentation talks about analysing compiled code and jar files. And the SQL that the tool can attribute to tables is parsed by a real SQL parser rather than by pattern matching on strings, which is why the MyBatis table name feature can claim MySQL support.

The Excel dependency is the one that stands out. A call graph tool that can export its output as a spreadsheet is a tool aimed at people who will take the result into a review meeting, not at a pipeline that consumes a graph format.

The project is published on Maven Central under com.github.adrninistrator for java-all-call-graph, and the licence is Apache-2.0, which is the permissive choice and suits a library meant to be embedded in other people's build tooling.

Running it: JDK 8, two configuration styles and a community to ask

The usage section is short on commands, which is consistent with a library rather than an application. The dependency environment needs JDK 8 or newer, and if you want to open the project in an IDE it recommends installing Gradle to manage the dependencies.

Configuration can be specified in two ways, by a configuration file or in code, and the README says the effect of the two is identical, because every configuration file and every configuration parameter has a corresponding item in the code. That is a sensible design for a library that has to work in an existing build, where a properties file is often the only configuration mechanism a team accepts. The configuration parameters themselves come in three formats, the first of which is a Map style key value form, and the parameters are split into two enums, one for the settings that are independent of the database and one for the settings that relate to it.

Around the tool there is a community layer worth knowing about. There is a WeChat group for static analysis discussion, with the note that the QR code only stays valid for seven days, so you add the contact first and mention a name before joining. The README also says the project is maintained in spare time only, that replies to questions therefore cannot be guaranteed to be timely, and that the suggestion is to open an issue on GitHub before discussing, so the material can be organised, and that later useful and non-duplicate questions and answers will be written up as documentation.

Two follow-on projects widen the surface. A web interface and an MCP version exist, with a separate server repository referenced for how they are built, and there are two documentation services for asking a model questions about the project, one of which needs no registration.

One adoption signal the README records is a list of technical articles found through public channels that mention using the library, including pieces on call graph construction for code security scanning, on code slimming design, and on a code analysis platform for precise testing.

Editorial conclusion

Adopt java-all-call-graph if your work involves impact analysis of a Java service, code slimming, precise test selection or a security scan that needs a call graph rather than a diagram, and you can accept running a two phase pipeline against your build artefacts. Do not adopt it for source level analysis of code that has never been compiled, since the analysis is described as working on compiled Java and jar files, and do not adopt it if you only need a one-off call tree, because this is a database and tooling project rather than a reporting tool. Verify first which JDK your build targets, since the README asks for JDK 8 or newer, how you will keep the database in step with the code, since the documentation is explicit that the analysis step must be rerun when the analysed code changes, and which of the framework parsers, MyBatis, Spring AOP, Spring Bean, Spring Controller or Spring Task, your codebase actually uses.

Frequently asked questions

What does java-all-call-graph do?

It performs automated static analysis of Java code and writes the result into a relational database so it can be queried with SQL. It parses classes, methods, fields, annotations, generics, method calls and enums, plus information from MyBatis, Spring AOP, Spring Bean, Spring Controller and Spring Task.

How does java-all-call-graph generate a full call chain?

From a given method it walks upward or downward through direct and indirect calls, producing a tree shaped result that the README describes as a subgraph of the overall call graph, and still a graph because cyclic calls are possible. A call stack is then a single path through that chain, in linked list form.

Which database tables does the MyBatis analysis attribute to a call?

The tool resolves which database tables a MyBatis mapper method operates on, for MySQL databases, both when generating full call chains and call stacks. The mapper XML and the SQL inside it are parsed rather than matched as strings, and the table name information is written into the method call information table.

What are the requirements for running java-all-call-graph?

The README asks for JDK 8 or newer, and recommends installing Gradle if you want to open the project in an IDE to manage dependencies. Configuration can be given through a configuration file or in code, with the same effect, and parameters come in three formats including a Map style key value form.

Official sources

  1. Adrninistrator/java-all-call-graph on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/adrninistrator-java-all-call-graph.svg)](https://hysenlabs.com/projects/adrninistrator-java-all-call-graph)

Was this useful?