Command-line options
codeanalyzer-java is a Picocli command. Invoke it as a fat JAR (java -jar codeanalyzer-2.3.7.jar ...) or, if you built a native image, as codeanalyzer ....
By default the analyzer writes one analysis.json per project. Pass --emit neo4j to project that same model into a Neo4j property graph instead — either a self-contained graph.cypher snapshot or a live, incremental push over Bolt. The Neo4j-specific flags below all hang off that mode.
Usage: codeanalyzer [-hvV] [--no-build] [--no-clean-dependencies] [--include-test-classes] [-a=<analysisLevel>] [-b=<build>] [-f=<projectRootPom>] [-i=<input>] [-o=<output>] [-s=<sourceAnalysis>] [-t=<targetFiles>]... [--emit=<emit>] [--app-name=<appName>] [--neo4j-uri=<uri>] [--neo4j-user=<user>] [--neo4j-password=<password>] [--neo4j-database=<db>]
Analyze java application.Options
Section titled “Options”| Flag | Argument | Description | Default |
|---|---|---|---|
-i, --input | path | Path to the project root directory to analyze. | — |
-s, --source-analysis | string | Analyze a single string of Java source instead of a project. No build required. | — |
-o, --output | path | Destination directory. Holds analysis.json for the default emit, graph.cypher for --emit neo4j without a URI, or schema.neo4j.json for --emit schema. If omitted, output goes to stdout. | stdout / cwd |
-a, --analysis-level | 1 | 2 | 1 = symbol table only; 2 = symbol table + call graph. | 1 |
-b, --build-cmd | string | Custom build command. When omitted at level 2, an auto build is used. | auto |
--no-build | flag | Do not build the application; use already-compiled output. | off |
--no-clean-dependencies | flag | Do not delete the downloaded _library_dependencies directory after analysis. | off |
-f, --project-root-path | path | Path to the root pom.xml / build.gradle (for multi-module projects). | value of -i |
-t, --target-files | path | A file to (re)analyze incrementally; repeatable. Forces level 1. | — |
--include-test-classes | flag | Also compile/analyze test sources. (Hidden option.) | off |
--emit | json | neo4j | schema | Output target. json writes analysis.json; neo4j projects the model into a Neo4j property graph; schema prints the graph schema contract. Matched case-insensitively. | json |
--app-name | string | Logical application name used as the :JApplication anchor that scopes the graph. (Neo4j emit only.) | input dir base name |
--neo4j-uri | uri | Bolt URI of a live Neo4j, e.g. bolt://localhost:7687. Its presence is what switches --emit neo4j from a snapshot to a live push. Falls back to NEO4J_URI. | — |
--neo4j-user | string | Neo4j username for the Bolt push. Falls back to NEO4J_USERNAME. | neo4j |
--neo4j-password | string | Neo4j password for the Bolt push. Falls back to NEO4J_PASSWORD. Prefer the env var. | neo4j |
--neo4j-database | string | Target Neo4j database. Falls back to NEO4J_DATABASE; when unset, the server default database is used. | server default |
-v, --verbose | flag | Print logs to the console. | off |
-h, --help | flag | Show help and exit. | — |
-V, --version | flag | Print version information and exit. | — |
Notes on key flags
Section titled “Notes on key flags”-i vs. -s
Section titled “-i vs. -s”-ipoints at a project directory on disk. This is the normal mode; dependencies are downloaded and (at level 2) the project is built.-spasses Java source as a string. The symbol table is built directly from that snippet with JDK-only type resolution — no project, no build, no dependency download.
Exactly one of these is the analysis subject. -s takes precedence when both are present.
-o (output)
Section titled “-o (output)”What lands in -o depends on --emit:
json(default) — writes<output>/analysis.json, creating the directory if needed. Without-o, the consolidated JSON goes to stdout — convenient for piping, and how the Python SDK can capture output without a temp file.neo4jwithout a URI — writes<output>/graph.cypher(defaults to the current working directory if-ois omitted).schema— writes<output>/schema.neo4j.json, or prints it to stdout when-ois omitted.
-a (analysis level)
Section titled “-a (analysis level)”See Analysis levels. Level 2 implies a build unless you pass --no-build or a custom -b. In the Neo4j projection, level 2 is also what adds J_CALLS edges (the WALA call graph) to the graph; level 1 emits the lossless symbol-table subgraph with no J_CALLS.
-t (target files)
Section titled “-t (target files)”See Incremental analysis. Repeat the flag for multiple files. Forces level 1; merges into an existing analysis.json when one is present in the output directory.
On a live Bolt push (--emit neo4j with a URI), -t marks the run as targeted: only the changed compilation units’ subgraphs are replaced, and orphan pruning of vanished units is skipped. A full run (no -t) prunes units whose source file has disappeared. See Neo4j output below.
Neo4j output
Section titled “Neo4j output”The four --emit neo4j modifiers (--app-name, --neo4j-uri, --neo4j-user, --neo4j-password, --neo4j-database) follow the same resolution order:
flag > environment variable > default
A flag wins when set; otherwise the matching env var is used; otherwise the built-in default.
| Flag | Environment variable | Default |
|---|---|---|
--neo4j-uri | NEO4J_URI | — (no URI → graph.cypher snapshot) |
--neo4j-user | NEO4J_USERNAME | neo4j |
--neo4j-password | NEO4J_PASSWORD | neo4j |
--neo4j-database | NEO4J_DATABASE | server default |
Keep credentials off the command line — prefer the NEO4J_PASSWORD environment variable to --neo4j-password, which would otherwise show up in shell history and process listings.
Two emit modes
Section titled “Two emit modes”Whether --emit neo4j writes a file or talks to a server is decided purely by whether a Bolt URI resolved (from --neo4j-uri or NEO4J_URI):
- No URI →
graph.cyphersnapshot. A self-contained, re-runnable Cypher script: constraints and indexes, a scoped wipe of this application’s prior subgraph, then batchedUNWIND ... MERGEfor nodes and edges. It expresses the full truth (it is not incremental). Load it withcypher-shell < graph.cypher. - URI present → live incremental Bolt push. The Bolt writer ensures constraints and indexes, diffs each compilation unit’s
content_hashagainst the live database, and replaces only changed units’ subgraphs via idempotentMERGEupserts. Shared:JPackage/:JAnnotationnodes are upserted once. On a full run it prunes units whose source file has vanished; a-ttargeted run skips that pruning.
--app-name is the tenancy key in both modes: it sets the name of the single :JApplication anchor, the wipe deletes only that application’s subgraph, and many applications can share one Neo4j database side by side, each rooted at its own :JApplication. When omitted, it defaults to the base name of the -i input directory. The :JApplication node also carries schema_version (1.0.0), the versioned schema contract the graph conforms to.
--emit schema
Section titled “--emit schema”--emit schema prints the machine-readable schema contract — every node label, relationship type, and property the projection can emit — and requires no project: it short-circuits before any analysis, so -i / -s are unnecessary. Writes schema.neo4j.json to -o if given, otherwise stdout.
java -jar codeanalyzer-2.3.7.jar --emit schema -o ./out # ./out/schema.neo4j.jsonjava -jar codeanalyzer-2.3.7.jar --emit schema # prints to stdoutExamples
Section titled “Examples”Write a re-runnable snapshot for one application:
java -jar codeanalyzer-2.3.7.jar \ -i /path/to/daytrader8 -a 2 \ --emit neo4j --app-name daytrader8 \ -o ./outcypher-shell -u neo4j -p "$NEO4J_PASSWORD" < ./out/graph.cypherPush live and incrementally over Bolt (credentials from the environment):
export NEO4J_PASSWORD=secretjava -jar codeanalyzer-2.3.7.jar \ -i /path/to/daytrader8 -a 2 \ --emit neo4j --app-name daytrader8 \ --neo4j-uri bolt://localhost:7687 \ --neo4j-user neo4j \ --neo4j-database neo4jRe-push only the files that changed (targeted — no orphan pruning):
java -jar codeanalyzer-2.3.7.jar \ -i /path/to/daytrader8 -a 2 \ --emit neo4j --app-name daytrader8 \ --neo4j-uri bolt://localhost:7687 \ -t src/main/java/com/example/AccountService.javaThe --app-name you load with is the same value a reader scopes to. In the Python SDK, Neo4jConnectionConfig(application_name="daytrader8") reads back exactly the graph produced by --app-name daytrader8 — no JDK, no JAR, no project sources, just the Bolt URI and read-only credentials. See the Neo4j guide for the producer/consumer split and the full schema.
Exit behavior
Section titled “Exit behavior”The command exits non-zero on failure. Run with -v to see the underlying logs (build invocation, dependency download, parse problems, WALA progress, and — for a live push — the Bolt connection and per-unit upserts) when diagnosing a failed run.
See worked invocations in Examples.