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

[jsr339-experts] Re: [jax-rs-spec users] Re: Matching algorithm doesn't recurse back on Locators

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Sun, 19 May 2013 18:50:05 +0100

Hi Bill - FYI, CXF has no problems with the tests you've mentioned, only
with that one we've been referring to.

I'll work on response to Santiago tomorrow, have to sign off now :-)

Cheers, Sergey

On 19/05/13 18:44, Bill Burke wrote:
> Well, there's a huge number of tests that fail in the TCK because of the
> new matching algorithm if implemented as-is:
>
> The whole set of:
>
> com.sun.ts.tests.jaxrs.ee.rs.pathparam.locator and .sub tests
>
> See my description here if you're interested:
>
> https://issues.jboss.org/browse/CTS-81
>
> This is the only part of the specification that is total crap, IMO. The
> algorithm is complex and leaves little room for optimization or
> interpretation, neither the TCK nor Jersey got it right either which
> just adds fuel to the fire. I had no problems passing the TCK prior to
> 2.0 and now, code that is stable and 4+ years old needs to be changed.
>
> On 5/19/2013 9:53 AM, Santiago Pericas-Geertsen wrote:
>> Hi Sergey,
>>
>> Let us focus on what the JAX-RS 1.1 spec states before we discuss
>> the best way to handle your example. Please run the JAX-RS 1.1
>> algorithm on your example and find the values for E, R_match and M in
>> step 2. I'd like to understand why it works in your analysis.
>>
>> Thanks.
>>
>> -- Santiago
>>
>> On May 17, 2013, at 4:42 PM, Sergey Beryozkin <sberyozkin_at_talend.com>
>> wrote:
>>
>>> Hi Santiago
>>> On 17/05/13 18:15, Santiago Pericas-Geertsen wrote:
>>>> Bill, Sergey,
>>>>
>>>> I can see the issue that you're reporting. However, and I don't
>>>> have a copy of the old spec handy, I believe HTTP method filtering
>>>> was also done in step 3 before, so why did it work before?
>>>>
>>>> The general idea of the algorithm has always been to avoid
>>>> backtracking; I think it would be possible to construct a more
>>>> involved example in which you'd need to backtrack more than one step
>>>> to match something.
>>>>
>>>> Could it be that your implementation always supported backtracking
>>>> but the TCKs didn't test that before?
>>>>
>>> No, we've never supported back-tracking. And as I tried to clarify,
>>> JAX-RS 1.1 did not even require it and CXF simply followed it to the
>>> letter.
>>>
>>> When we have
>>>
>>> @Path("/")
>>> public class Resource {
>>> @POST
>>> @Path("sub")
>>> public void post();
>>>
>>> @Path("{id}")
>>> public Resource locator() {
>>> }
>>>
>>> @GET
>>> public void get();
>>> }
>>>
>>> and
>>>
>>> GET /sub
>>>
>>> returning 404 is simply not the option IMHO.
>>>
>>> JAX-RS 1.1 adds two candidates, post() & locator() and the text
>>> clearly makes locator() win and hence get() selected. No
>>> backtracking, simple comparison or check: post() has a non-matching
>>> method, it is out
>>>
>>> Likewise if we have
>>>
>>> @Path("/")
>>> public class Resource {
>>> @GET
>>> @Path("{id}")
>>> public void get();
>>>
>>> @Path("{id}")
>>> public Resource locator() {
>>> }
>>>
>>> @GET
>>> public void getSub();
>>> }
>>>
>>> we have the same 2 candidates, but get() wins because locator() loses
>>> due to the text preferring Tmethod to Tlocator.
>>>
>>> Whichever way you go, there's absolutely no need for the
>>> backtracking. The only case where backtracking might be required id
>>> when two locators have exactly the same Path, but 2.0 correctly
>>> recommends to report an error in this case.
>>>
>>> FYI, in 1.1, originally sublocators were winning in the latter case,
>>> and I recall myself when the decision was made to make sure that
>>> get() in the 2nd example wins, but the bottom line is that both get()
>>> and locator() has always been two candidates to be selected from.
>>>
>>> We have tests on the above and the documentation on this case.
>>> It is backward-incompatible spec change, please check 1.1 text.
>>>
>>> We have to keep 1.1 behavior, we can not break the existing code with
>>> 2.0
>>>
>>> Thanks, Sergey
>>>
>>>
>>>
>>>
>>>
>>>> -- Santiago
>>>>
>>>> On May 17, 2013, at 8:59 AM, Bill Burke <bburke_at_redhat.com> wrote:
>>>>
>>>>>
>>>>>
>>>>> On 5/17/2013 4:35 AM, Sergey Beryozkin wrote:
>>>>>> Hi Bill
>>>>>> On 17/05/13 04:41, Bill Burke wrote:
>>>>>>> Let me give you an example:
>>>>>>>
>>>>>>> Given this request:
>>>>>>>
>>>>>>> OPTIONS /sub
>>>>>>>
>>>>>>> This will match:
>>>>>>>
>>>>>>> @Path("/")
>>>>>>> class Resource {
>>>>>>>
>>>>>>> @Path("{id}")
>>>>>>> public Locator locator() { return new Locator();}
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> class Locator {
>>>>>>>
>>>>>>> @OPTIONS
>>>>>>> public String options() { return "OK"; }
>>>>>>> }
>>>>>>>
>>>>>>> But this won't match:
>>>>>>>
>>>>>>> @Path("/")
>>>>>>> class Resource {
>>>>>>>
>>>>>>> @GET
>>>>>>> @Path("sub")
>>>>>>> public String get() { return "OK"; }
>>>>>>>
>>>>>>> @Path("{id}")
>>>>>>> public Locator locator() { return new Locator();}
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>> Seems to me it will too. @GET method is selected only if no
>>>>>> @OPTIONS is
>>>>>> available and in this case it is available.
>>>>>>
>>>>>
>>>>> Check out the spec. It won't match because "sub" is matched in
>>>>> 2(h). 2(h) says that if there are any non-locator matches, then go
>>>>> to 3, then 3(a) will abort the request.
>>>>>
>>>>> I ran into this very problem when testing against the TCK. The TCK
>>>>> assumes there is no loopback to Locators and one of the tests
>>>>> fails. I'm able to fix this problem quite easily, but, I have some
>>>>> users that reported this as a "bug". They will now "regress".
>>>>>
>>>>>
>>>>> --
>>>>> Bill Burke
>>>>> JBoss, a division of Red Hat
>>>>> http://bill.burkecentral.com
>>>>
>>>
>>>
>>> --
>>> Sergey Beryozkin
>>>
>>> Talend Community Coders
>>> http://coders.talend.com/
>>>
>>> Blog: http://sberyozkin.blogspot.com
>>
>