I agree. I was focussed on the reader. Given that <?> in the writer, it's
clear that you are correct.


On Mon, Sep 7, 2009 at 8:33 AM, Sergey Beryozkin <sbery...@progress.com>wrote:

> Hi Benson
>
> In MessageBodyWriter.writeTo() it's actually Class<?> which is in the
> signature. And there's no return value.
>
> We could've implemented just MessageBodyWriter as opposed to
> MessageBodyWriter<Object> but it would stiill cause warning in the user test
> code....
>
> I can agree that implementing MessageBodyWriter<Object> delegates the
> type-safety checks to the actual provider and thus makes that <T> thing
> useless. But for providers choosing to implement MessageBodyWriter<Book> the
> runtime will now ensure the class of the object to be written is assignable
> to Book.class (now that we've implemented the message body provides sorting
> requirement from JAXRS 1.1).
>
> Please don't get me wrong, may be it would be the best option indeed to go
> ahead with passing Object.class MessageBodyWriter<Object> - but I'm afraid
> it will turn the bunch of user providers out there broken...
>
> thanks, Sergey
>
> ----- Original Message ----- From: "Benson Margulies" <
> bimargul...@gmail.com>
> To: <dev@cxf.apache.org>
> Sent: Monday, September 07, 2009 1:06 PM
> Subject: Re: JAX-RS and generics
>
>
> Sergey,
>
> With Java generics, there's a pattern:
>
>  <T> public T gloop(Class<T> type, whatever)
>
> That pattern requires that you pass in the class of what you expect to get
> out.
>
> If XXXProvider implements MessageBodyReader<T>, then it must have a
> implement the read API against the same T. You can't, legitimately, cast it
> to MessageBodyReader<Book>.
>
> So, if AegisProvider implements MessageBodyReader<Object>, and you want to
> write clean code that does not get warnings, you have to write:
>
> Object o = p.read(Object.class, ...)
>
> If it implements MessageBodyReader<T>, you then AegisProvider<Book> does
>
>  Book b = p.read(Book.class, ...)
>
> Now, if the people who invented JAX-RS have decided to ignore this pattern
> and force us to write code that needs @SuppressWarning("unchecked"), well,
> I'm sad but I'll stop sending email. Since my generic AegisProvider passes
> tests, however, ...
>
>
>
>
> On Mon, Sep 7, 2009 at 5:50 AM, Sergey Beryozkin <sbery...@progress.com
> >wrote:
>
>
>>
>> https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/ext/MessageBodyWriter.html#writeTo(T,%20java.lang.Class,%20java.lang.reflect.Type,%20java.lang.annotation.Annotation[],%20javax.ws.rs.core.MediaType,%20javax.ws.rs.core.MultivaluedMap,%20java.io.OutputStream)<https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/ext/MessageBodyWriter.html#writeTo%28T,%20java.lang.Class,%20java.lang.reflect.Type,%20java.lang.annotation.Annotation%5B%5D,%20javax.ws.rs.core.MediaType,%20javax.ws.rs.core.MultivaluedMap,%20java.io.OutputStream%29>
>> <
>> https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/ext/MessageBodyWriter.html#writeTo%28T,%20java.lang.Class,%20java.lang.reflect.Type,%20java.lang.annotation.Annotation%5B%5D,%20javax.ws.rs.core.MediaType,%20javax.ws.rs.core.MultivaluedMap,%20java.io.OutputStream%29
>> >
>>
>>
>> type - the class of object that is to be written.
>>
>> So I don't think we should pass Object.class for
>> MessageBodyWriter<Object>.
>> If one would like to avoud doing casts during testing then it should be
>> just
>>  MessageBodyWriter<Book> and I'm pretty sure the runtime will pass
>> Book.class.
>>
>> Cheers, Sergey
>>
>>
>>
>>  On Sat, Sep 5, 2009 at 1:57 PM, Benson Margulies <bimargul...@gmail.com
>>
>>> >wrote:
>>>
>>>  JAX-RS defines two fundamental interfaces: MessageBodyReader<T> and
>>>
>>>> MessageBodyWriter<T>, and providers implement.
>>>>
>>>> I claim that GENERIC providers that work for any object (like those
>>>> corresponding to data bindings) should, themselves, be GENERIC, and
>>>> implement MessageBodyX<T>, not MessageBodyX<Object>.
>>>>
>>>>
>>>>  Allow me to modulate this claim. I thought about it some more.
>>>
>>> If you want to define a class as 'implements MessageBodyX<Object>', fine.
>>> However, the right thing to pass to the Class<T> argument will ALWAYS be
>>> Object.class. If you want to cue in the code to the sort of object in
>>> flight, use the Type argument further down the parameter list.
>>>
>>>
>>>
>>>  I claim this because the whole API structure of MessageBodyX assumed
>>>> this.
>>>> It uses Class<T> in a way that requires constant
>>>> @SupressWarnings("unchecked") if the base is MessageBodyX<Object>.
>>>>
>>>> To put my money where my mouth is, as it were, I implemented this for
>>>> the
>>>> Aegis providers. When I did this, I discovered that the JAX-RS runtime
>>>> code
>>>> couldn't handle generic type providers. When the provider type is, say,
>>>>
>>>> AegisElementProvider<Book>
>>>>
>>>> then implemented interface comes up as MessageBodyReader<T>, not
>>>> MessageBodyReader<Book>. So it is a TypeVariable, not a class or a
>>>> ParameterizedType.
>>>>
>>>> I fixed the provider selection code to cope, but I didn't write the
>>>> additionally complex code to look at bounds and insist that if there is
>>>> a
>>>> bound the type at hand be within it.
>>>>
>>>>
>>>>
>>>
>>
>

Reply via email to