Skip to content

v3.1.1

Choose a tag to compare

@github-actions github-actions released this 08 Sep 10:39
· 13 commits to main since this release
fdab050

Install

pip install codeanalyzer-java==3.1.1   # bundles a JVM; installs the canjv launcher

Or the jar with a codeanalyzer launcher (requires Java 11+):

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/codellm-devkit/codeanalyzer-java/releases/download/v3.1.1/codeanalyzer-installer.sh | sh

Or run the JAR directly (requires Java 11+):

# JSON output, at the analysis level you ask for
java -jar codeanalyzer.jar -i /path/to/project -a 4 -o ./out          # writes out/analysis.json

# Neo4j projection - always full depth, so it takes no --analysis-level
java -jar codeanalyzer.jar -i /path/to/project --emit neo4j -o ./out  # writes out/graph.cypher

Downloads

Asset Description
codeanalyzer.jar Self-contained analyzer (run with java -jar)
codeanalyzer-installer.sh Installer that fetches the jar and adds a codeanalyzer launcher
schema.neo4j.json Neo4j graph schema contract (node labels, relationships, DDL)

📦 Other Changes

  • docs: the PyPI install needs a real JDK from -a 2 onwards
  • feat(cli): --strict fails a run whose analysis degraded
  • chore(release): 3.1.1
  • feat(id): can:///java/… — the app becomes the outermost segment, and the graph root gets its id
  • docs(plan): can:///java/… identity migration
  • feat(ids): @external drops the language segment; document the polyglot rule

⚠️ Breaking: the can:// id grammar changed

Every durable id moved. The application is now the outermost segment:

before   can://java/<app>/<file>/<type>/<signature>
after    can://<app>/java/<file>/<type>/<signature>

before   can://artifact/<app>/<path>            after   can://<app>/artifact/<path>
before   can://java/<app>/@external/<type>/<sig> after   can://<app>/@external/<type>/<sig>

@external and artifact deliberately omit the language segment: they are language-neutral shared merge targets, so codeanalyzer-python and codeanalyzer-typescript mint byte-identical ids for the same file or library symbol. This release converges Java onto the shape those two already use.

schema_version remains 2.0.0, so this change is NOT detectable from the payload. A stored analysis.json or Neo4j graph written by 3.1.0 or earlier holds old-shape ids that will no longer join against 3.1.1 output. The analyzer version is the only signal. If you have persisted ids, re-analyze.

Neo4j: existing databases need one upgrade push, and it is handled. :JApplication now merges on its can://<app> id rather than the free-text --app-name, and the legacy j_application_name uniqueness constraint is dropped before any load — without that, the first push against a pre-3.1.1 database would fail with ConstraintValidationFailed. Verified end to end against Neo4j 5.

The Cypher wipe now covers the whole can://<app>/ prefix, which brings :Artifact and :ConfigKey inside it. They are rebuilt by every snapshot instead of accumulating forever. One deliberate consequence: a cross-language edge into a shared :Artifact is dropped by one analyzer's snapshot and restored on the other's next push. :Package (pkg: purls) sits under no application and is never wiped.

What this does not do: the app id is derived from --app-name, so two services analyzed under the same name still merge onto one root. Give each service its own --app-name.

New: --strict

A degraded run — the RTA overlay or the L4 semantic ddg unavailable — previously exited 0 with only a WARN on stderr. --strict turns any such degradation into a non-zero exit that names what was lost, and writes no analysis.json, so a pipeline cannot mistake a thin payload for a complete one. Opt-in: degrading remains a supported mode.

Relevant if you install from PyPI: the bundled jdk4py runtime is a JRE with no javac, so -a 2 and above need a real JDK on JAVA_HOME. Without one, RTA and the semantic ddg silently drop — which is exactly what --strict surfaces.