Markus Jung created TOMEE-4659:
----------------------------------
Summary: REST: request to an unmatched @Path returns 405 instead
of 404 when the request verb collides with another resource method
Key: TOMEE-4659
URL: https://issues.apache.org/jira/browse/TOMEE-4659
Project: TomEE
Issue Type: Bug
Reporter: Markus Jung
A JAX-RS request whose path matches _no_ resource class must return 404 (Not
Found). TomEE instead returns 405 (Method Not Allowed) in one specific shape:
when the request's HTTP verb happens to match the verb of an unrelated resource
method that lives at a different path.
This was originally reported as the second half of TOMEE-4643 and is split out
here because it is an independent defect with a different root cause than the
Feature/DynamicFeature discovery gap (which is fixed under TOMEE-4643).
h2. TCK reference
Jakarta RESTful Web Services 4.0 TCK
({{jakarta.ws.rs:jakarta-restful-ws-tck:4.0.1}}):
*
{{ee/jakarta/tck/ws/rs/spec/resource/annotationprecedence/subclass/JAXRSClientIT.java#incorrectPathOnClassTest}}
— expects 404, TomEE returns 405.
Note this test is _not_ currently excluded, so the JAX-RS TCK suite is failing
on it today.
h2. Reproduction
A minimal, self-contained Arquillian reproduction (no TCK dependency) is added
under:
{{arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/precedence/}}
The application exposes exactly one resource: {{PUT /resource/put}} (class
{{@Path("resource")}}, method {{@PUT @Path("put")}}), with a superclass
carrying {{@POST @Path("super")}} and an interface carrying {{@GET
@Path("interfaceresource")}} — both overridden per JAX-RS
annotation-inheritance rules, so neither is exposed. Servlet mapped at {{/*}}
via web.xml (mirroring the TCK).
Results:
* {{PUT /resource/put}} -> 200 (sanity, passes)
* {{POST /super/post}} -> 404 (unmatched path, unrelated verb, passes)
* {{PUT /interfaceresource/put}} -> *405, expected 404* (the bug)
The difference between the two unmatched-path cases is only the HTTP verb:
{{PUT}} collides with the verb of the one real method ({{PUT /resource/put}}),
{{POST}} does not.
The repro test {{AnnotationPrecedenceSubResourceTest#unknownPathIsNotFound}} is
committed with {{@Ignore}} pointing at this ticket so CI stays green until the
fix lands; the two sanity assertions run.
h2. Root cause is _not_ in CXF's core matching (investigated)
Two standalone reproductions against the real CXF 4.2.2 sources/jars rule out
the obvious CXF suspects:
h1. Calling {{JAXRSUtils.selectResourceClass}} + {{findTargetMethod}} directly
with path {{/interfaceresource/put}} and the single {{@Path("resource")}}
resource returns _404_ — the class template {{/resource(/.*)?}} does not match
{{/interfaceresource}}, so {{pathMatched}} stays 0 and CXF correctly selects
404.
h1. {{HttpUtils.getPathToMatch}} returns {{/interfaceresource/put}} _unchanged_
for every base address the {{/*}} mapping can produce ({{"/"}}, {{""}},
{{"/resource"}}) — the path is not truncated.
So the 405 originates in TomEE's servlet-deployment integration handing CXF a
different effective path/state than the raw request, not in CXF's
status-selection logic. Next investigative step: run the repro with
{{org.apache.cxf.jaxrs}} logging at FINE and inspect the {{START\_CRI\_MATCH}}
/ {{CRI\_SELECTED}} lines to see the exact path and template CXF matches; that
identifies the TomEE class to fix (likely in openejb-cxf-rs / openejb-rest
request routing).
h2. Environment
* TomEE 11.0.0-SNAPSHOT (main)
* CXF 4.2.2
--
This message was sent by Atlassian Jira
(v8.20.10#820010)