Skip to content

fix: compose JAX-RS method-level @Path with class-level prefix#1007

Open
CharlesQueiroz wants to merge 1 commit into
DeusData:mainfrom
CharlesQueiroz:fix/jaxrs-path-composition
Open

fix: compose JAX-RS method-level @Path with class-level prefix#1007
CharlesQueiroz wants to merge 1 commit into
DeusData:mainfrom
CharlesQueiroz:fix/jaxrs-path-composition

Conversation

@CharlesQueiroz

Copy link
Copy Markdown

Fixes #1005.

Root cause

extract_route_from_annotations() returned on the first mapping annotation. For JAX-RS methods the verb and the path live in two sibling annotations:

@GET
@Path("/count")
public CountResponse count() { ... }

The @GET matched first (annotation_route_method("GET")), defaulted the path to "/", and the sibling @Path was never read: every method-level @Path was silently dropped. Class-level @Path prefixes were never recognized either, because a lone @Path carries no verb, so the scan reported "no route" and spring_class_route_prefix() returned NULL.

This also explains the "inconsistent" symptom in #1005: resources whose endpoints are exercised by RestAssured tests got Route nodes from the tests' full-URL string literals, masking the missing annotation-derived routes; resources without such tests showed only the class-level route.

Fix

New scan_route_annotations() collects the whole annotation set in one pass: the mapping verb (+ optional inline path, Spring style) and a separate JAX-RS @Path value. Then:

  • method-level (extract_route_from_annotations): a verb annotation is still required (a lone @Path sub-resource locator is not an endpoint); path = inline mapping path, else @Path, else "/".
  • class-level (spring_class_route_prefix): inline mapping path (@RequestMapping("/api")), else class-level @Path.
  • Bare @HEAD/@OPTIONS verbs are now recognized alongside GET/POST/PUT/DELETE/PATCH.

Spring extraction is unchanged: mapping annotations keep their inline path and the collecting scan preserves the first-mapping-annotation-wins order.

Validation

  • New regression test extract_java_jaxrs_path_composition_issue1005 (class prefix alone, prefix + method @Path, verb preserved).
  • Full suite: 5986 passed, 1 skipped, 0 failures.
  • End-to-end fixture (sanitized copy of the failing resource shape from Java/JAX-RS: method-level @Path sub-routes inconsistently composed with class-level prefix #1005, constructor @ConfigProperty params and generic DTO return types included) indexed with the patched binary now yields:
    • __route__GET__/api/v1/widgets
    • __route__GET__/api/v1/widgets/count
    • __route__POST__/api/v1/widgets/{}/archive
    • Spring control __route__GET__/api/v2/things/all unchanged.

…ata#1005)

JAX-RS splits a route across two annotations: the verb comes from a bare
@GET/@POST/... and the path from a sibling @path. The annotation scan
returned on the first mapping annotation, so the @get matched, defaulted
the path to "/" and the sibling @path was never read. Class-level @path
was never recognized as a prefix either, because a lone @path carries no
verb and the scan reported no route.

scan_route_annotations() now collects the whole annotation set (mapping
verb + optional inline path, and a separate JAX-RS @path), then:
- method-level: verb required; path = inline mapping path, else @path,
  else "/"
- class-level prefix: inline mapping path, else @path
Also recognizes bare @HEAD/@options verbs.

Spring behavior is unchanged (mapping annotations keep their inline
path); covered by the existing test suite plus a new regression test.
@CharlesQueiroz CharlesQueiroz requested a review from DeusData as a code owner July 10, 2026 16:04
@DeusData DeusData added bug Something isn't working parsing/quality Graph extraction bugs, false positives, missing edges priority/normal Standard review queue; useful PR with ordinary maintainer urgency. labels Jul 10, 2026
@DeusData DeusData added this to the 0.9.1-rc milestone Jul 10, 2026
@DeusData

Copy link
Copy Markdown
Owner

Thanks for the targeted JAX-RS fix. I have triaged it into 0.9.1-rc as the fix candidate for #1005. Review focus will be class-plus-method path composition and making sure Spring-style annotation extraction does not regress.

@DeusData

Copy link
Copy Markdown
Owner

Reviewed and verified locally — the diagnosis and fix are exactly right; same two mechanical blockers as your #1008, plus one recommendation.

Verified (your branch merged onto current main, db330bf):

  • your unit test passes; extraction suite 214/214
  • end-to-end on a real index: the JAX-RS resource now yields /api/v1/widgets and /api/v1/widgets/count (previously both methods collapsed onto a single __route__GET__/ node — independently reproduced on main before applying your branch)
  • Spring non-regression confirmed end-to-end: @RestController + class @RequestMapping("/api/orders") + @GetMapping("/list") still composes to /api/orders/list

1. DCO (blocking): commit 07704e1 lacks a Signed-off-by matching its author — git commit --amend -s + force-push.

2. clang-format (blocking): two lines in extract_defs.c (~1299–1300, the HEAD/OPTIONS condition) need wrapping — make lint-format locally shows the exact form.

3. Recommendation (would take this from good to complete): add an end-to-end Route-node test alongside the unit test — tests/test_edge_types_probe.c has et_routes_exact, which asserts the exact Route-node name set through the full pipeline. That's the tier that matches the reporter's actual symptom (collapsed/missing Route nodes and the dedup onto __route__GET__/), and it guards the class-prefix composition + emission dedup path your unit test can't see. Shape:

static const char *routes[] = {"/api/v1/widgets", "/api/v1/widgets/count", NULL};
ASSERT_TRUE(et_routes_exact(f, 1, routes));

If you'd rather keep this PR minimal, say so and we'll add the probe-tier guard in a follow-up after merge.

Known gap we're both fine deferring: @ApplicationPath base-path composition (cross-class, like Spring's cross-file case) — worth its own issue once this lands.

With DCO + format in and CI green, this is good to merge from my side. Two solid, well-scoped fixes in a row — much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working parsing/quality Graph extraction bugs, false positives, missing edges priority/normal Standard review queue; useful PR with ordinary maintainer urgency.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Java/JAX-RS: method-level @Path sub-routes inconsistently composed with class-level prefix

2 participants