Repository navigation
Description
Problem
Ten tests under tests/analysis/java/ fail with
TypeError: argument should be a str or an os.PathLike object where __fspath__ returns a str, not 'NoneType'
raised at cldk/analysis/java/codeanalyzer/_jdk.py:166 (home = Path(java_cache_dir) / "jdk" / JDK_RELEASE). java_cache_dir arrives as None from cldk/analysis/java/codeanalyzer/codeanalyzer.py:113:
java_cache = Path(self.analysis_json_path) if self.analysis_json_path else cache_subdir(None, self.project_dir, "java")
java_home = ensure_jdk(java_cache)cache_subdir(None, None, "java") returns None by contract ("None if no root can be determined"), and ensure_jdk evaluates Path(java_cache_dir) before its $JAVA_HOME fallback at :172, so a system JDK cannot rescue it. Any construction with neither a cache dir nor a project dir — the source-code / pipe modes these tests use — hits it.
Failing: 8 in test_inheritance_call_graph.py, 2 in test_java_analysis.py (Should return a symbol table for source analysis…, Should return per-variable initializer text for fields).
Why it was never caught
It was caught, and shipped anyway. The v1.5.0 release run (30300820857, commit dd4870d, Linux, Python 3.11, GraalVM 21) reports:
===== 11 failed, 253 passed, 33 skipped, 28 warnings in 382.74s (0:06:22) ======
✗ Should return a symbol table for source analysis with expected class/method count
and still published, because the "Delete tag on failure" step tested steps.test.conclusion == 'failure', which is never true for a continue-on-error step. #306 (30b3fa1, "Fix dead release test gate: use outcome, not conclusion") repaired that gate after v1.5.0. There is no PR CI in this repo, so the release run is the only place the suite executes.
Reproduced on this machine under Python 3.14 and, in a separately synced environment, Python 3.12: identical 10 failures. Java code and tests are byte-identical to v1.5.0 apart from 22 deleted lines in test_jcodeanalyzer.py.
Consequence
With the gate now live, the next tag pushed to this repo — v2.0.0rc2 is queued — will run make test, fail on these ten, and delete itself. This blocks every release until fixed.
Suggested fix
Either or both:
- Never hand
ensure_jdkaNone. When no cache root can be determined, fall back to a stable per-user location (e.g.platformdirs-style~/.cache/cldk/java, or the existing default the JSON path uses when a project is present) so the JDK has somewhere to live. One line atcodeanalyzer.py:113, plus a guard inensure_jdkthat raises a clearCodeanalyzerExecutionExceptioninstead of aTypeErrorif it is stillNone. - Retire the source-analysis witnesses. fix(java): source-code analysis crashes with Path(None) — JDK cache resolution assumes a project dir #256 records Java single-file mode as won't-fix with removal in 2.0.0, and Release workflow test gate is dead —
continue-on-errorforcesconclusion=success; flip to outcome + make CI suite honestly green #255 retires its witness tests. If those two tests are removed under Release workflow test gate is dead —continue-on-errorforcesconclusion=success; flip to outcome + make CI suite honestly green #255, only the eighttest_inheritance_call_graph.pycases need the code fix — check how they construct the backend; they may be reaching the same path via a fixture with no project dir.
Watch for a second-order effect: once ensure_jdk has a real home, a test environment without a $JAVA_HOME that carries jmods will attempt a Temurin download. The tests already mock the analyzer subprocess; they should mock _get_codeanalyzer_exec (or ensure_jdk) as well rather than depend on the network.
Definition of done
uv run pytest --pspec --cov=cldk --cov-fail-under=33(the exactmake testthe release gate runs) is 0 failed on Linux/Python 3.11 — verified by an actual workflow run, not a local pass, since that is the only CI this repo has.- No test in
tests/analysis/java/performs a network download. - If tests are removed, the removal cites Release workflow test gate is dead —
continue-on-errorforcesconclusion=success; flip to outcome + make CI suite honestly green #255.
Caveats
- A
workflow_dispatchonrelease.ymlwould publish; do not use it to test. Either add a minimal test-only workflow (this repo has none) or push the tag and let the gate decide — the latter is acceptable only if the tag deletion is understood to be the expected failure mode of a bad tag.
Blocks the 2.0.0rc2 cut (#327). Independent of the 2.0 legs (#322, #323): the failure predates them and their diff does not touch cldk/analysis/java.
Activity
fix(java): retire source-mode witnesses and refuse a None cache dir (#…
rahlk commentedon Sep 6, 2026
Fixed by #329, merged into
release/2.0asff0d00c. The exact release command (uv run pytest --pspec --cov=cldk --cov-fail-under=33) now reports 613 passed / 184 skipped / 0 failed on that commit, verified independently after the PR's own run. The ten source-mode witnesses are skip-gated citing #255/#256;ensure_jdknow finds its own nested cache instead of re-downloading every process. #255 is not fully discharged by this (its items 2, the scratch-tag gate exercise, and mirroring tomainremain).