jsr370-experts@jax-rs-spec.java.net

Re: [jax-rs-spec users] _at_Path with regular expression overrides other @Path's with the same URI

From: Bill Burke <bburke_at_redhat.com>
Date: Fri, 16 Oct 2015 10:13:23 -0400

On 10/15/2015 5:09 PM, Markus KARG wrote:
> What about adding the ability for an application to provide a MatchingStrategyProvider?
>

I can't see anybody ever wanting to write one. So -1000.

> Like simply packing a POJO in the WAR file that is annotated by @Provider and implements any custom algorithm wanted? That way we could keep the spec as-is, and Bill and Sergey could simply wrap their existing "non-compliant but intuituve" algorithms as .class files, so developers can put that .class file into their WAR and have a WORA solution.
>
> Feasible?
>

-1000. Fix the spec. There's really no reason not to support
backtracking in the matching algorithm. It makes zero sense to return
405 or 404 responses when there is a resource method that could be
matched by backtracking. Furthermore, it is highly doubtful that
backtracking would break existing Jersey apps as these apps don't rely
on backtracking. IMO, this change would be akin to adding a method to
an interface.

This simple program shows how silly the matching algorithm is:

@Path("/doc.txt")
@GET

@Path("/doc.pdf")
@GET

@Path("/{document}")
@DELETE

It is a well known best practice to use URLs rather than content
negotiation. Yet, in this simple program, the user would also have to
write explicit @DELETE methods for doc.txt and doc.pdf even though a
catch all would work just fine.

Here's some other ones too:

http://bill.burkecentral.com/2013/05/29/the-poor-jax-rs-request-dispatching-algorithm/

Resteasy changed its matching algorithm prior to the JAX-RS 2.0 TCK
specifically because users asked us to.






> -Markus
>
>
> -----Original Message-----
> From: Bill Burke [mailto:bburke_at_redhat.com]
> Sent: Donnerstag, 15. Oktober 2015 15:52
> To: jsr370-experts_at_jax-rs-spec.java.net
> Subject: Re: [jax-rs-spec users] @Path with regular expression overrides other @Path's with the same URI
>
> The right thing to do is to improve the matching algorithm. I could
> also refer you to a bunch of "bug" reports where people are complaining
> about the matching algorithm. I then have to explain to them that this
> isn't a "bug" but a "feature". I also must say that there are far fewer
> ISVs than regular JAX-RS developers that stick to one implementation.
> Changing the TCK for one edge case that may break 2 different products
> that are 7+ years old with thousands upon thousands of downloads doesn't
> sound like the best way to make Java EE developers happy.
>
> It is Jersey and the spec that should change. Changing the matching
> algorithm will in most cases effect no Jersey users.
>
> On 10/15/2015 8:11 AM, Marek Potociar wrote:
>> Hi Sergey,
>>
>> Well, the discussion on the Jersey thread clearly shows how confusing it is if the implementations are not 100% compliant with the spec. You either are compliant or you are not. There are no shades of gray when it comes to official spec compliance. If you pass TCK, you are compliant, if you don’t you are not. If there is a hole in TCK coverage, it may get fixed later and then you would need to pass the fixed TCK to be compliant.
>>
>> The standard specifications are here to ensure application portability for users. From the user perspective a pure JAX-RS code must behave the same way on ANY implementation that claims to be JAX-RS compliant.
>>
>> Marek
>>
>>
>>> On 15 Oct 2015, at 01:03, Sergey Beryozkin <sberyozkin_at_talend.com> wrote:
>>>
>>> Hi Markus
>>>
>>> I'd like to refer to the other thread where you agreed we should not rush it.
>>> Yes, as it currently stands - RestEasy and CXF are not compliant in this specific case.
>>>
>>> However IMHO we should strive really hard not to treat such cases as this is how it should and that is it.
>>> I think it is more of a spec text being non-intentionally too strict in this case - lets give it a chance - if Santiago can find an opportunity to 'fix' it then we will all win, if not then at least we gave it another try
>>>
>>> Cheers, Sergey
>>> On 14/10/15 21:41, Markus KARG wrote:
>>>> Sergey,
>>>>
>>>> I understand your arguments, but for users (and for TCK) compliance is a true/false question. As an ISV I need to rely on the fact that matching works exactly the same on all implementations (at least as long the spec does not provide a means for an application to provide its own matching algorithm).
>>>>
>>>> So what do we tell people now? They wait for an answer. Are CXF/RestEasy definitively non-compliant or not?
>>>>
>>>> -Markus
>>>>
>>>> -----Original Message-----
>>>> From: Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
>>>> Sent: Montag, 12. Oktober 2015 22:33
>>>> To: jsr370-experts_at_jax-rs-spec.java.net
>>>> Subject: Re: @Path with regular expression overrides other @Path's with the same URI
>>>>
>>>> Hi Santiago
>>>>
>>>> I was thinking on the way home, I thought the sentence where the 'M' set is built from Rmatch = R(Td) is a bit strict.
>>>> I recall the explicit regular expressions were added at the last moment in 1.0, the current text covers a situation with same verbs OK (in that Jersey issue I thought there were two GETs where I'd indeed expect the method with an explicit reg expression win)...
>>>>
>>>> Rmatch = R(Td) condition blocks a GET method from being included in M (referring to that example).
>>>> I suspect replacing a '=' symbol with another one implying Rmatch is equal or equivalent to R(Td).
>>>> I suspect I might've got confused with my analysis above but I open an issue
>>>>
>>>> Markus, I'm not sure the fact CXF/Reasteasy would not select DELETE makes either implementation broken :-).
>>>> My opinion the spec text is far from being perfect in this specific case which I agree makes CXF/RestEasy is not compliant here but perhaps in this case the spec text can be optimized before a new TCK test is added :-).
>>>>
>>>> Thanks, Sergey
>>>>
>>>>
>>>>
>>>> On 12/10/15 19:22, Santiago Pericasgeertsen wrote:
>>>>>> On Oct 12, 2015, at 1:03 PM, Markus KARG <markus_at_headcrashing.eu> wrote:
>>>>>>
>>>>>> Sergey,
>>>>>>
>>>>>> so what is the conclusion now? CXF is broken and you will fix it?
>>>>> Let’s file it as an issue and review it later. I had a quick look at the algorithm and, frankly, it is not as clear as I hoped so but I don’t have the cycles to look at it deeper at this point.
>>>>>
>>>>> — Santiago
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
>>>>>> Sent: Montag, 12. Oktober 2015 17:26
>>>>>> To: jsr370-experts_at_jax-rs-spec.java.net
>>>>>> Subject: Re: @Path with regular expression overrides other @Path's
>>>>>> with the same URI
>>>>>>
>>>>>> Hi Santiago
>>>>>>
>>>>>> That long discussion we last had, that was related to a case where a
>>>>>> matching subresource locator was discarded, even though it was having
>>>>>> a matching method, as opposed to the current resource class.
>>>>>> It still 'hurts' whenever I think about it.
>>>>>>
>>>>>> But in this case it is different, no backtracking of any sort is even
>>>>>> needed here - it is so simple...
>>>>>>
>>>>>> So we are at 3.7.2.2.e: "Sort E using the number of literal
>>>>>> characters in each member as the primary key (descending order), the
>>>>>> number of capturing groups as a secondary key (descending order), the
>>>>>> number of capturing groups with non-default regular expressions (i.e.
>>>>>> not
>>>>>> '([^/]+?)') as the tertiary key
>>>>>> (descending order)..."
>>>>>>
>>>>>> Then yeah, DELETE is supposed to be selected. This is so sad. The
>>>>>> only consolation, regular expressions are not that popular...
>>>>>> Sergey
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 12/10/15 14:31, Santiago Pericasgeertsen wrote:
>>>>>>> All,
>>>>>>>
>>>>>>> First, obviously I agree the result is counter-intuitive. Second,
>>>>>>> we
>>>>>> have had this this discussion many in the times in the past ;), and
>>>>>> basically the same algorithm since JAX-RS 1.0 AFAIK. Third, the
>>>>>> algorithm does not backtrack or look ahead, and thus makes a decision
>>>>>> first on Path and then on method resulting in the observed behavior
>>>>>> -because it discarded potential matches too soon.
>>>>>>> If an implementation behaves differently, it is because it is
>>>>>> implementing a different algorithm from the one in the spec. Ideally
>>>>>> we should change the algorithm, but unfortunately it is not a
>>>>>> backward compatible change.
>>>>>>> - Santiago
>>>>>>>
>>>>>>>> On Oct 12, 2015, at 9:08 AM, Sergey Beryozkin
>>>>>>>> <sberyozkin_at_talend.com>
>>>>>> wrote:
>>>>>>>> Oh, that is actually completely broken, I agree, I thought there
>>>>>>>> were two
>>>>>> GET methods there, my fault.
>>>>>>>> I honestly can not see how that can be resolved as works as expected...
>>>>>>>>
>>>>>>>> Sergey
>>>>>>>>
>>>>>>>>
>>>>>>>> On 12/10/15 14:00, Bill Burke wrote:
>>>>>>>>> If this is true, then the matching algorithm is showing yet again,
>>>>>>>>> how
>>>>>> effed up it is. The @Get method in the example should always
>>>>>> resolve. It makes sense intuitively. In Resteasy if the @Delete path
>>>>>> resolved first, but the methods didn't match, we would "backtrack" and try the get method.
>>>>>>>>> On 10/11/2015 12:00 PM, Sergey Beryozkin wrote:
>>>>>>>>>> Jersey is correct in that example - a template var with a regex
>>>>>>>>>> wins over a basic template var.
>>>>>>>>>>
>>>>>>>>>> The spec clearly states that an expression with more literal
>>>>>>>>>> chars
>>>>>> wins.
>>>>>>>>>> So I guess a regex expression can only win if, besides the rex-ex
>>>>>>>>>> expression itself, a given path has more literal chars, say,
>>>>>>>>>> abc[d|e] would win over abc - I think this can only happen when
>>>>>>>>>> choosing between multiple matching root resources.
>>>>>>>>>>
>>>>>>>>>> Or it can win in that Jersey JIRA issue - a number of literal
>>>>>>>>>> chars beyond the regex is equal but the regex method wins because
>>>>>>>>>> a template var is more specific. I'll double check with CXF - I
>>>>>>>>>> doubt it works
>>>>>> diff
>>>>>>>>>> in CXF
>>>>>>>>>>
>>>>>>>>>> Sergey
>>>>>>>>>>
>>>>>>>>>> On 11/10/15 08:28, Markus KARG wrote:
>>>>>>>>>>> Experts,
>>>>>>>>>>>
>>>>>>>>>>> in a discussion on the Jersey user group someone claimed that
>>>>>>>>>>> the behaviour of Jersey is different from CXF and RestEasy. As
>>>>>>>>>>> that would imply both, an inaccuracy of the TCK (it does not
>>>>>>>>>>> detect the
>>>>>>>>>>> deviation) and a violation of the specification in CXF and
>>>>>>>>>>> RestEasy (as Jersey is the RI, hence axiomatically cannot be
>>>>>>>>>>> wrong), we should quickly clarify the truth in that claim.
>>>>>>>>>>>
>>>>>>>>>>> The case is recorded in Jersey's issue tracker including source
>>>>>>>>>>> code
>>>>>>>>>>> (https://java.net/jira/browse/JERSEY-2942) and is simple to explain:
>>>>>>>>>>>
>>>>>>>>>>> *Given a resource has two methods, annotated as **_at_GET
>>>>>>>>>>> @Path(//<PathParam>/) and **_at_DELETE @Path(//<RegEx>/)*
>>>>>>>>>>>
>>>>>>>>>>> *When a client invokes **GET <RootURI>//<PathParam>/ upon that
>>>>>> resource*
>>>>>>>>>>> *Then the result is **405 Method Not Allowed*
>>>>>>>>>>>
>>>>>>>>>>> While this looks pretty odd to the average Joe (as there is a
>>>>>>>>>>> perfect match of GET and /<PathParam>/), it was claimed that
>>>>>>>>>>> this is _compliant_ to the specification (since regex have
>>>>>>>>>>> higher priority than literals, and methods are matched after URIs).
>>>>>>>>>>>
>>>>>>>>>>> It was reported that CXF and RestEasy return 200 OK instead,
>>>>>>>>>>> while the RI does return 405 Method Not Allowed.
>>>>>>>>>>>
>>>>>>>>>>> Certainly an application MUST return the same status code on ANY
>>>>>>>>>>> JAX-RS compliant implementations, so we should clarify ASAP the
>>>>>>>>>>> following questions:
>>>>>>>>>>>
>>>>>>>>>>> (1) @SpecLeads: Is the use case described above (regex beats
>>>>>>>>>>> literals) really compliant to the JAX-RS specification, and how
>>>>>>>>>>> to explain /to the average Joe/ the reasonability of ignoring
>>>>>>>>>>> the apparently perfect match?
>>>>>>>>>>>
>>>>>>>>>>> (2) @SpecLeads: Is there a bug in the TCK so it does not detect
>>>>>>>>>>> the deviation of CXF and RestEasy?
>>>>>>>>>>>
>>>>>>>>>>> (3) @Vendors: Can you please check your implementations whether
>>>>>>>>>>> they really violate the spec? Do you have plans to fix it?
>>>>>>>>>>>
>>>>>>>>>>> I think we all have a vital interest in clarifying it, as a
>>>>>>>>>>> standard makes only sense when it is reasonable and commonly
>>>>>>>>>>> accepted, so I would be glad if you could answer the above
>>>>>>>>>>> points rather soon. :-)
>>>>>>>>>>>
>>>>>>>>>>> Thanks
>>>>>>>>>>>
>>>>>>>>>>> -Markus
>>>>>>>>>>>
>>>>
>>>
>>
>

-- 
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com