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. >>>> >>>> >>>> >>> >> >