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

[jsr339-experts] Re: [jax-rs-spec users] Re: HEADS-UP: Revise MBR selection mechanism?

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Thu, 24 May 2012 16:14:54 +0100

On 24/05/12 15:16, Bill Burke wrote:
>
>
> On 5/24/12 5:43 AM, Sergey Beryozkin wrote:
>> On 23/05/12 18:14, Marek Potociar wrote:
>>>
>>> On May 23, 2012, at 6:43 PM, Bill Burke wrote:
>>>
>>>> On 5/23/12 12:04 PM, Marek Potociar wrote:
>>>>>
>>>>> On May 23, 2012, at 4:49 PM, Sergey Beryozkin wrote:
>>>>>
>>>>>> On 23/05/12 15:37, Marek Potociar wrote:
>>>>>>> Hello experts,
>>>>>>>
>>>>>>> please review the following issue
>>>>>>> http://java.net/jira/browse/JAX_RS_SPEC-187 and provide your
>>>>>>> feedback.
>>>>>>> Apparently this may be considered a BW-breaking change. If we make
>>>>>>> it,
>>>>>>> the implementations may need to provide a BW compatibility switch if
>>>>>>> necessary.
>>>>>>
>>>>>> I do not understand that issue at all. The resource method returns
>>>>>> InputStream therefore the MBW supporting InputStream must win
>>>>>
>>>>> Not necessarily - see the section of the spec referenced from the
>>>>> issue - 4.2.2, step 4.
>>>>>
>>>>> The response media types takes precedence over the generic MBW type,
>>>>> so if the response is "application/json" InputStream and a custom
>>>>> Jackson JSON provider claims to support any java type (Object) for
>>>>> "application/json",
>>
>>>>> it will win over the default InputStream provider that supports
>>>>> InputStream for any media type.
>>
>> No, it will only win over default InputStream provider in case of
>> Accept: application/json, for all other types the default one wins.
>>
>>
>> That is however most likely not what the user wanted.
>>>>>
>>>>> The issue suggests to reverse this ordering.
>>>>>
>>>>> Also, the spec mandates that custom providers should always take
>>>>> precedence over the default ones, but the spec is not clear whether
>>>>> this should really be a primary or tertiary key. For MBW the issue
>>>>> suggests that the right thing would be to explicitly define it as a
>>>>> tertiary key.
>>
>> I'm nervous this is going to break the fundamental expectation that the
>> custom provider wins.
>>
>> I think what is suggested is a workaround to manage catch-all providers
>> that return true in readFrom or writeTo.
>>
>> At this moment of time I believe that the right course of action is to
>> recommend the custom provider implementations to be more selective, ex,
>> providers managing POJOs should exclude InputStream.class, but...
>>
>>>>>
>>>>>
>>>>
>>>> To have to separate implementations (Jersey and Resteasy) come to the
>>>> same separate conclusion I think gives pretty good reason to change
>>>> the algorithm.
>>>>
>>>> Beyond InputStream, really any "low-level" type would have to be
>>>> treated as a special case in the current matching algorithm:
>>>> InputStream, Reader, File, StreamingOutput, String, char[], and
>>>> byte[]. Plus, if a user has a specific MBR/MBW for a specific type,
>>>> then they probably want that MBR/MBW called no matter what. You can't
>>>> get any more specific than the Java type.
>>
>> I don't have a good answer to it.
>> Still, I believe that these are not main-stream cases at all.
>> Having a situation where a custom JSON/etc provider helping the service
>> dealing with POJOS, where the service also return byte[], etc of the
>> same media type is rare and seems unusual.
>>
>> Why one would have a service with two methods, one returning Book &
>> another - InputStream ? Just get two separate endpoints if that is
>> really needed. I guess that can be tricky to do in cases where the
>> scanning gets the providers loaded and visible to all the web
>> application, but the scanning is an optional feature.
>>
>> IMHO, The following course of action:
>> - recommend the custom providers to be as specific as possible in
>> readFrom/writeTo
>> - get a user to register a custom provider for InputStream, byte[],
>> String supporting a specific media type when really needed - it's very
>> very easy.
>>
>> needs to be reviewed alongside the proposed change of the algorithm.
>>
>> In this case the control is for the user to assert. In the proposed
>> change we are making an assumption that this is user will not want, etc,
>> based on the case centered around InputStream or primitive classes.
>>
>> Consider the case where a custom provider supports reading both Document
>> and DOMSource, example, in order to consolidate the way DOM is
>> processed. Its generic type is Object.
>>
>
> That is really bad practice, to have one MBR/MBW service multiple Java
> types. But maybe I'm not understanding your example?
>
>
isnt it what JAXB/JSON/etc providers are actually doing all the time ?

>
> Maybe this sheds more light?
>
> More specific types are used as the first sort key. So, if your Java
> type matches exactly to the generic type parameter of the MBR/MBW, it
> will be chosen over every other one.
>
>
> @Consumes("application/json")
> public class JsonReader implements MessageBodyReader<Object> {} //builtin
>
> @Consumes("*/*")
> public class InputStreamReader implemetns MessageBodyReader<InputStream>
> {} // builtin
>
>
> @Consumes("application/json")
> public class JsonInputStreamReader implements
> MessageBodyReader<InputStream> {} // application provided provider
>
this is exactly what I'm suggesting above.
>
> Consider this method:
>
> @POST
> public void post(InputStream is);
>
>
> Content-Type: application/json, JsonInputStream gets picked
> Content-Type: text/plain, InputStreamReader gets picked
>
> Make more sense?
>
Yes it does. What exactly in the current algorithm prevents it is from
happening now ? JsonInputStreamReader simply wins (InputStream is more
specifc than Object)

Sergey

>