Repository navigation
Description
Problem
The Java backend carries its analyzer two ways that the other backends do not: the jar is checked in and force-included under cldk/analysis/java/codeanalyzer/jar/ (release.yml injects another copy at build time, #336), and cldk/analysis/java/codeanalyzer/_jdk.py downloads a pinned Temurin JDK with jmods/ into <cache_dir>/java/jdk/ on first use, exporting JAVA_HOME because the analyzer's WALA scope read $JAVA_HOME/jmods. That is ~35 MB in every cldk wheel and a ~200 MB download per project cache, plus JDK-resolution code the SDK has to maintain.
codeanalyzer-java 3.0.2 removes the reason for all of it (codeanalyzer-java#222): the analyzer reads its primordial scope from the running JVM through jrt:/, so no JAVA_HOME and no jmods/ are needed, and it ships on PyPI as codeanalyzer-java, a pure wheel with the jar under _bin/ and jdk4py (Temurin 21) as the runtime. The package exposes jar_path(), java_path() and command(*args), the same seam codeanalyzer-typescript.bin_path() gives the TypeScript backend.
Scope boundary
In scope: pyproject.toml depends on codeanalyzer-java==<pin> next to the other two backends, and the pin in [tool.backend-versions] becomes real; JCodeanalyzer._get_codeanalyzer_exec returns codeanalyzer_java.command(); delete _jdk.py, _locate_jar, the checked-in jar, the [tool.hatch.build] artifacts force-include, and the jar inject/verify steps in release.yml; tests that monkeypatch ensure_jdk follow.
Out of scope: the Java model migration to schema v2 (#310) — but it is a prerequisite, because the only current wheel is 3.0.2 (v2 output; the 2.3.7 on PyPI is a stale native-image build). Land this on top of leg 3, or in the same PR if the pin bump is small.
Goals
-
pip install cldkon a machine with no Java runsCLDK.java(...)atAnalysisLevel.call_graph - No
JAVA_HOMEis read or set by the SDK; no JDK is downloaded; no jar is checked in or injected - The
codeanalyzer-javapin is the single source of the analyzer version, and release.yml no longer fetches fromreleases/latest(closes the mechanism release.yml ignores the codeanalyzer-java pin and bundles releases/latest #336 patches)
Caveats and known risks
codeanalyzer-javapinsjdk4py>=21,<22: WALA 1.6.x's Shrike rejects class files above version 67, and jdk4py 25 ships version 69. The SDK inherits that pin transitively; nothing to do unless an SDK dependency ever wants jdk4py 25.jdk4pycarries aGPLv2license classifier (Temurin's GPLv2 + Classpath Exception, like every JDK). License scanners on downstream Apache-2.0 trees may flag it; document it, do not work around it.- Windows:
codeanalyzer_java.__main__falls back tosubprocess.callthere; the SDK already spawns viasubprocess, so no change, but it is untested on Windows. cache_dirno longer hosts a JDK. Single-file source mode (fix(java): source-code analysis crashes with Path(None) — JDK cache resolution assumes a project dir #256) loses the "cannot host a JDK" failure and should now just work; confirm rather than assume.
Definition of done
- Fresh venv with no Java on PATH and
JAVA_HOMEunset:CLDK.java(project_path=<daytrader8>, analysis_level=AnalysisLevel.call_graph).get_call_graph()returns the same edge set the previous JDK-download path returned (1876 edges on daytrader8 at analyzer 3.0.2; 1391 declared+rta, 375 rta, 110 declared) grep -r 'JAVA_HOME\|ensure_jdk\|jmods' cldkis empty;cldk/analysis/java/codeanalyzer/jar/and_jdk.pyare gone- Built wheel contains no
.jar;unzip -l dist/*.whl | grep -c '\.jar$'is 0 - Java test suite green with the
ensure_jdkmonkeypatch removed
Activity
python-sdk2.0 — a static-analysis front end for humans and agents .github#55rahlk commentedon Sep 6, 2026
Measured the definition-of-done numbers before wiring this up, and the packaging change is provably neutral — but the absolute edge counts in the DoD do not match this repo's own fixture.
All three runs below use the sources in
tests/resources/java/application/daytrader8-1.2.zip(138.javafiles), at-a 4:declared+rtartadeclared_jdk.py-provisioned Temurin 21.0.5+11codeanalyzer_java.command(),--no-build,JAVA_HOMEunsetcommand(), with the Maven auto-build (Maven 3.9.16 present)So the old JDK-download path and the wheel return the identical edge set, and the build/no-build choice makes no difference on this project. The DoD's 1876 / 1391 / 375 / 110 is 14 edges higher; the likely cause is a different daytrader8 tree, since
tests/conftest.pydownloads daytrader8 from GitHub when the zip is absent.Suggest the DoD assert equality between the two paths on the same sources rather than a literal count, which is the property that actually matters here and does not drift with the corpus.
Two more things confirmed while checking:
analysis.jsonkey sets are identical to 3.0.1 at envelope, application, module, type, callable and body-node level, andschema.neo4j.jsonis byte-identical (contract2.0.0, same labels and relationship types). Models written against 3.0.1 need no change.codeanalyzer_javaexposescommand(*args) -> List[str],jar_path(),java_path(),__version__(3.0.2);command()returns[<jdk4py java>, -jar, <wheel jar>, *args]and the run needs noJAVA_HOME. The wheel is 35 MB plusjdk4py(Temurin 21.0.8).On the license caveat:
jdk4py's PyPI classifier says plain GPLv2, but the shipped runtime carries GPLv2 with the Classpath Exception (java-runtime/legal/java.base/LICENSEplusASSEMBLY_EXCEPTION) — the ordinary OpenJDK terms, and the exception is what permits Apache-2.0 code to run on it. Nothing about this repo's licensing changes; the only new thing is that dependency tooling now sees a GPLv2-classified row where a runtime JDK download was invisible to it. Worth one sentence in the docs, as the issue says.This is folded into leg 3a (#310) as its own task, so no 35 MB jar enters git history on the way.
docs(java): record the schema-v2 migration, the 3.0.1 floor and the s…
feat(java): drive the analyzer through the codeanalyzer-java wheel an…
docs(java): record the schema-v2 migration, the 3.0.1 floor and the s…
feat(java): drive the analyzer through the codeanalyzer-java wheel an…
docs(java): record the schema-v2 migration, the 3.0.1 floor and the s…
feat(java): drive the analyzer through the codeanalyzer-java wheel an…