users@jax-rs-spec.java.net

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

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Tue, 20 Oct 2015 21:40:25 +0100

On 16/10/15 16:00, Bill Burke wrote:
> I bet you can count on one hand the users that wanted plug in their
> own matching strategy. Personally, I just can't justify that amount
> of work just to satisfy a very small handful of users.
So on one hand it is your unfounded bet based on exactly what ? On the
other hand is a positive experience we've achieved in CXF with users
being able to easily experiment with the matching algorithm.
IMHO it would be a very useful feature to have, to be able to minimally
affect the algo. The truth is, it is impossible to have a 100% perfect
algorithm at the spec level

Markus, see, I like this idea of yours :-)

Sergey

>
> Supporting backtracking allows support for some very simple use cases
> that I get asked about all the time.
>
> I've argued in the past that supporting backtracking does not break
> backward compatibility. Marek and Santiago disagreed...Thus here we are.
>
> On 10/16/2015 10:31 AM, Sergey Beryozkin wrote:
>> Bill, I'd say it is a bit too strong.
>> I've had many users in CXF successfully using a custom matching
>> strategy, for example, before 2.0 spec improved the selection between
>> multiple matching class resources on the same path, when choosing
>> between multiple equal candidates based on a number of query/etc
>> parameters, etc.
>>
>> I'm all for improving the algorithm. But I somehow suspect that a
>> strategy path can make improving the algo more realistic as there will
>> be a two-way link.
>>
>> Sergey
>> On 16/10/15 15:13, Bill Burke wrote:
>>>
>>>
>>> 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
>>>>>>>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>