Skip to content

Analysis levels

The -a / --analysis-level flag selects how much work codeanalyzer-java does. There are two levels.

LevelProducesBuilds the project?Relative cost
1 (default)symbol_table onlyNo (source parse only)Fast
2symbol_table + call_graphYes, by defaultSlower
Terminal window
java -jar codeanalyzer-2.3.7.jar -i /path/to/project -a 1 -o ./output

Level 1 runs only the Javaparser pipeline. It parses every .java file and produces the symbol table: all types, their fields, methods and constructors, comments, and imports — with source locations, method bodies, and cyclomatic complexity.

It does not build the project. Library dependencies are still downloaded for type resolution (so qualified names resolve), but no compilation of your code is required. This makes level 1 the fast path, suitable when you only need program structure — not who-calls-whom.

Terminal window
java -jar codeanalyzer-2.3.7.jar -i /path/to/project -a 2 -o ./output -v

Level 2 does everything level 1 does, then runs WALA to build an interprocedural call graph. The result is a call_graph array of caller→callee edges added alongside the symbol table.

Because WALA analyzes the compiled program, level 2 builds the project by default (auto-detecting Maven or Gradle). You can control this:

  • -b "<cmd>" — supply a custom build command instead of auto-build.
  • --no-build — skip building entirely; use this when the project is already compiled.

See Build integration for how the build is invoked.

The analysis level governs the Neo4j projection the same way it governs analysis.json. Level 1 emits the lossless symbol-table subgraph — compilation units, types, callables, fields, and the rest — with no J_CALLS edges. Level 2 adds the call graph as (:JCallable)-[:J_CALLS]->(:JCallable) relationships on top of it.

This carries through the -t downgrade: because passing -t with -a 2 forces level 1, a targeted incremental Bolt push (--emit neo4j -t ...) replaces only the changed units’ symbol-table subgraphs and carries no call edges. Refresh J_CALLS with a full level-2 run.

  • Use level 1 when you need the program’s structure: listing classes and methods, reading method bodies, finding fields, extracting Javadoc, surveying imports, or doing incremental per-file updates.
  • Use level 2 when you need reachability or call relationships: who calls a method, what a method transitively reaches, or seeding a taint/reachability query from an entry point.