Skip to content

Read the primordial scope from jrt:/ and ship codeanalyzer-java on PyPI with a bundled JVM - #223

Merged
rahlk merged 1 commit into
mainfrom
fix/issue-222-jrt-scope-pypi-wheel
Sep 6, 2026
Merged

Read the primordial scope from jrt:/ and ship codeanalyzer-java on PyPI with a bundled JVM#223
rahlk merged 1 commit into
mainfrom
fix/issue-222-jrt-scope-pypi-wheel

Conversation

@rahlk

@rahlk rahlk commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

Closes #222

What

  • ScopeUtils loads WALA's primordial scope from the running JVM via jrt:/ instead of $JAVA_HOME/jmods. No JAVA_HOME, no jmods, any runtime.
  • New com.ibm.cldk.utils.JrtModule: WALA's own one closes its stream before returning it (1.6.7 through 1.8.0).
  • packaging/python: pure wheel codeanalyzer-java = fat jar + jdk4py>=21,<22 runtime + canjv launcher. One wheel for all platforms; jdk4py's platform wheels carry the JVM.
  • release.yml: tag must equal gradle.properties; builds and publishes the wheel via PyPI Trusted Publishing alongside the jar.
  • Bump to 3.0.2.

Verified

daytrader8, jdk4py 21, JAVA_HOME unset, no jmods on the machine:

run result
-a 2 1876 edges (1391 declared+rta, 375 rta, 110 declared), set-identical to the jmods baseline
-a 3 --l3-engine wala byte-identical analysis.json
fresh venv, pip install wheel, canjv -a 2 same edge set
./gradlew test 508/509 pass; the one failure is the Docker-only integration test (no Docker here)

Before tagging

PyPI Trusted Publishing must be configured on the codeanalyzer-java project for this repo and release.yml, or the publish step fails.

…ith a bundled JVM

WALA's primordial scope was loaded by walking $JAVA_HOME/jmods, which tied the
analyzer to a full JDK with jmods and a JAVA_HOME. Unset, level 2 silently fell
back to declared-only edges and the L3/L4 WALA engine was unavailable.

The scope now comes from the JVM running the analysis, through the jrt:/
filesystem (lib/modules), so any runtime works, including jlink'd ones. WALA's
own JrtModule cannot be used: it closes its Files.list stream inside
try-with-resources before returning it, and iterating fails with "source already
consumed or closed" (still true in 1.8.0). A small eager JrtModule under
com.ibm.cldk.utils replaces it.

packaging/python builds a pure wheel, codeanalyzer-java, with the fat jar under
_bin/ and jdk4py (Temurin 21) as the runtime, installing a canjv launcher. jdk4py
is pinned below 22 because Shrike 1.6.7 rejects class files above version 67.

release.yml verifies the tag against gradle.properties, builds the wheel after
the jar, and publishes it to PyPI via Trusted Publishing, so jar and wheel stay
in lockstep. Bump to 3.0.2.

Verified on daytrader8 under jdk4py 21 with JAVA_HOME unset: -a 2 edge set equal
to the jmods baseline (1876 edges), -a 3 --l3-engine wala byte-identical.

Closes #222
@rahlk
rahlk merged commit 7b89281 into main Sep 6, 2026
@rahlk
rahlk deleted the fix/issue-222-jrt-scope-pypi-wheel branch September 6, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Read the primordial scope from jrt:/ and ship codeanalyzer-java on PyPI with a bundled JVM

1 participant