feat(java): take up codeanalyzer-java 3.1.0 — config-read tiers and the entrypoint report - #371
Merged
Merged
Conversation
…he entrypoint report 3.1.0 adds three application-scope overlays: the entrypoint pass's coverage record (codeanalyzer-java#235) and the code-to-config layer in two tiers, a literal tier (#233) and a dataflow tier closed over the L3 DDG and the L4 call graph (#237). The graph contract stays at 2.0.0, but the Java models are extra="forbid", so a 3.1.0 payload did not parse at all until they grew the five new fields. Models mirror the wire: JEntrypointReport, JConfigUse and JConfigRead (the last two are PyConfigUseEdge/PyConfigRead's fields verbatim), entrypoint_frameworks on JCallable and JType, and the three overlays on JApplication as Optional — the one place in that file where None and [] are different answers. get_config_uses, get_unresolved_config_reads, get_config_readers and get_entrypoint_coverage are implemented once on JavaAnalysisBackend over the canonical JApplication, which JNeo4jBackend now rebuilds with the overlays in it (two more statements, and only on a graph that carries them). The two tiers are surfaced through prov rather than flattened: a key reached over dataflow is weaker evidence than a literal at the call site. The refusal is kept and measured from the data. It is deliberately NOT the config layer's own absence, which is ambiguous both ways: the analyzer writes config_uses/config_reads_unresolved only when non-empty (the a4 fixture is a level-4 3.1.0 run that reads no configuration and carries neither key), and the graph declares J_USES_CONFIG/J_READS_CONFIG_UNRESOLVED only once an edge exists. The witness is the sibling overlay from the same release — 3.1.0 writes an entrypoint report on every run, 3.0.x writes none of the three — so all three are probed as the one analyzer generation they are, and no version literal enters the decision path. Verified rather than assumed, against a graph emitted by 3.1.0: - The relationship names are J_USES_CONFIG and J_READS_CONFIG_UNRESOLVED, not the JAVA_ prefix a comment on #231 proposed. That agrees with PY_/TS_ on the concept and differs only in each language's own node prefix, so there is no parity-clause problem to settle upstream. - The projection still carries no comment nodes: :JComment is a declared label with zero nodes. remove_all_comments and the file-keyed Neo4j comment accessors stay blocked and stay documented as such. Fixtures regenerated with 3.1.0 and every published figure in their README re-measured: both files are identical to their 3.0.3 copies apart from the version stamp and the additive fields, and no figure moved. Closes #369
…he uptake moved 7691 re-emitted with codeanalyzer-java 3.1.0, both applications (daytrader8 18,354 nodes, thingsboard) so the graph stays the two-application scope audit. Three live figures moved, each re-measured rather than adjusted: - SCALE_EXTERNALS 2,570 -> 2,571. The new :JExternal is not a call target: J_READS_CONFIG_UNRESOLVED points at a ghost, so ThingsBoard's @value reads mint @external/org.springframework.beans.factory.annotation.Value/value() where nothing calls it. - The whole-database ssa DDG count 324,959 -> 324,952, all seven in ThingsBoard. - get_ddg over Neo4j now carries 276 points-to edges on daytrader8 that the same analyzer's analysis.json does not — and it is a difference of what each source was asked, not of the projection. codeanalyzer-java 3.1.0 makes the level-4 points-to layer depend on --external-calls, which --emit neo4j forces on and which the SDK's local run does not pass; 3.0.3 produced the same edges either way. Four runs of the same tree: 3.0.3 -a 4 -> 10,430 (1,134 points-to); 3.1.0 -a 4 -> 10,154 (858); 3.1.0 -a 4 --external-calls -> 10,430, set for set identical to the graph; 3.1.0 --emit neo4j -> 10,430. The graph is a strict superset and the payload has nothing the graph lacks, so the three affected tests assert the containment, its exact size and that every edge in the gap is points-to — a regression in either direction still fails, and fails naming what it is. Worth reporting upstream: the flag is documented as controlling only whether out-of-project call targets are homed as external_symbols. Also fixes a refusal that could be skipped: get_config_readers short-circuited on a key the application does not declare, so it answered [] on a 3.0.x analysis where every sibling raised. It now goes through get_config_uses, and the refusal test covers the undeclared-key case.
…-canj-310 # Conflicts: # CHANGELOG.md # docs/agent-api-reference.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #369.
codeanalyzer-java3.1.0 adds config-read tiers (upstream #233, #237) and the entrypoint report (#235).get_config_readersandget_unresolved_config_readsstop returning[]unconditionally, andget_entrypoint_coveragestops reporting the report unavailable.The models were the task
A 3.1.0 payload failed
JApplicationvalidation with 1,368 errors across five fields —entrypoint_frameworkson everyJCallableandJType, plusentrypoint_report/config_uses/config_reads_unresolvedon the application root.extra="forbid"is why that surfaced as a loud failure instead of silently dropped data.Added
JEntrypointReport,JConfigUse,JConfigRead, mirroring the wire — which spells them exactly as Python'sPyApplicationalready does.The four accessors are implemented once on
JavaAnalysisBackendover the canonicalJApplication, whichJNeo4jBackendnow rebuilds with the overlays in it; both per-backendreturn []stubs are gone.provsurfaces the tier rather than flattening it, so a caller can tell a literal read at the call site from one inferred over the DDG.The refusal probe is not the config layer's absence
The obvious probe is wrong in both directions, and I measured why:
config_uses/config_reads_unresolvedonly when non-empty — the a4 fixture is a real 3.1.0 level-4 run over a tree that reads no configuration, and carries neither key.Either would refuse a clean 3.1.0 analysis that genuinely reads nothing — an ambiguous empty of exactly the kind this closes. The witness used instead is the sibling overlay from the same release: 3.1.0 writes an entrypoint report on every run; 3.0.x writes none of the three. One probe, no version literal, both directions pinned.
Verified, not assumed
J_USES_CONFIGandJ_READS_CONFIG_UNRESOLVED. TheJAVA_prefix mentioned on codeanalyzer-java#231 did not ship. Agrees withPY_*andTS_*on the concept, differing only by each language's own node prefix.:JCommentis a declared label with zero nodes, and only a declaration'sdocstringreaches the graph.remove_all_commentsstays inRAISINGand the file-keyed Neo4j comment accessors keep refusing, recorded as a standing limitation.Upstream regression found and filed — codeanalyzer-java#240
3.1.0 makes the level-4
points-totier depend on--external-calls, which was unconditional before:ddgpoints-to-a 4-a 4-a 4 --external-calls--emit neo4jforces the flag and the in-process backend never passes it, so the graph is now a strict superset of the payload by 276 edges and the same slice reaches further over Neo4j. Three live tests moved from equality to containment plus exact size plus all-points-to. Measured and recorded rather than worked around.One contract test carries an argued exemption
test_generic_methods_are_all_abstract_on_the_java_contractrequires every generic-ABC method to stay abstract, which conflicts with answering the config layer once for both backends. Exactly those two are excluded by name, and a new test asserts by identity that neither backend overrides them — a more direct guarantee of the property that matters than "is abstract" was, and one that goes stale loudly if the design changes.Verification
Full gate 1584 passed, 367 skipped, 85.27% (baseline 1571 / 367 / 85.22%). Java live against the re-emitted two-application 3.1.0 graph with every gate satisfied: 728 passed, 2 skipped. Both fixtures regenerated with every published README figure re-measured — nothing moved but the version stamp and the additive fields.