cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Benson Margulies <bimargul...@gmail.com>
Subject Re: JAX-RS and generics
Date Mon, 07 Sep 2009 12:06:13 GMT
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 <sberyozk@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>
>
> 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 <bimargulies@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.
>>>
>>>
>>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message