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

From: Sergey Beryozkin <>
Date: Fri, 16 Oct 2015 15:31:00 +0100

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.

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}")
> 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:
> 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 []
>> Sent: Donnerstag, 15. Oktober 2015 15:52
>> To:
>> 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 <>
>>>> 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 []
>>>>> Sent: Montag, 12. Oktober 2015 22:33
>>>>> To:
>>>>> 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
>>>>>>> <> 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 []
>>>>>>> Sent: Montag, 12. Oktober 2015 17:26
>>>>>>> To:
>>>>>>> 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 "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
>>>>>>>>> <>
>>>>>>> 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
>>>>>>>>>>>> ( 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