Re: JAX-RS and generics

2009-09-07 Thread Benson Margulies
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 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 but it would stiill cause warning in the user test
> code
>
> I can agree that implementing MessageBodyWriter delegates the
> type-safety checks to the actual provider and thus makes that  thing
> useless. But for providers choosing to implement MessageBodyWriter 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 - 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: 
> Sent: Monday, September 07, 2009 1:06 PM
> Subject: Re: JAX-RS and generics
>
>
> Sergey,
>
> With Java generics, there's a pattern:
>
>   public T gloop(Class type, whatever)
>
> That pattern requires that you pass in the class of what you expect to get
> out.
>
> If XXXProvider implements MessageBodyReader, then it must have a
> implement the read API against the same T. You can't, legitimately, cast it
> to MessageBodyReader.
>
> So, if AegisProvider implements MessageBodyReader, 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, you then AegisProvider 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  >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.
>> If one would like to avoud doing casts during testing then it should be
>> just
>>  MessageBodyWriter and I'm pretty sure the runtime will pass
>> Book.class.
>>
>> Cheers, Sergey
>>
>>
>>
>>  On Sat, Sep 5, 2009 at 1:57 PM, Benson Margulies >
>>> >wrote:
>>>
>>>  JAX-RS defines two fundamental interfaces: MessageBodyReader and
>>>
>>>> MessageBodyWriter, 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, not MessageBodyX.
>>>>
>>>>
>>>>  Allow me to modulate this claim. I thought about it some more.
>>>
>>> If you want to define a class as 'implements MessageBodyX', fine.
>>> However, the right thing to pass to the Class 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 in a way that requires constant
>>>> @SupressWarnings("unchecked") if the base is MessageBodyX.
>>>>
>>>> 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
>>>>
>>>> then implemented interface comes up as MessageBodyReader, not
>>>> MessageBodyReader. 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.
>>>>
>>>>
>>>>
>>>
>>
>


Re: JAX-RS and generics

2009-09-07 Thread Sergey Beryozkin

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 but it would stiill cause warning in the user 
test code


I can agree that implementing MessageBodyWriter delegates the type-safety checks to the actual provider and thus makes that 
 thing useless. But for providers choosing to implement MessageBodyWriter 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 - but I'm afraid it will turn the bunch of user providers out there broken...


thanks, Sergey

- Original Message - 
From: "Benson Margulies" 

To: 
Sent: Monday, September 07, 2009 1:06 PM
Subject: Re: JAX-RS and generics


Sergey,

With Java generics, there's a pattern:

   public T gloop(Class type, whatever)

That pattern requires that you pass in the class of what you expect to get
out.

If XXXProvider implements MessageBodyReader, then it must have a
implement the read API against the same T. You can't, legitimately, cast it
to MessageBodyReader.

So, if AegisProvider implements MessageBodyReader, 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, you then AegisProvider 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 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.
If one would like to avoud doing casts during testing then it should be just
 MessageBodyWriter and I'm pretty sure the runtime will pass
Book.class.

Cheers, Sergey



 On Sat, Sep 5, 2009 at 1:57 PM, Benson Margulies 
>wrote:

 JAX-RS defines two fundamental interfaces: MessageBodyReader and

MessageBodyWriter, 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, not MessageBodyX.



Allow me to modulate this claim. I thought about it some more.

If you want to define a class as 'implements MessageBodyX', fine.
However, the right thing to pass to the Class 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 in a way that requires constant
@SupressWarnings("unchecked") if the base is MessageBodyX.

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

then implemented interface comes up as MessageBodyReader, not
MessageBodyReader. 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.










Re: JAX-RS and generics

2009-09-07 Thread Benson Margulies
Sergey,

With Java generics, there's a pattern:

public T gloop(Class type, whatever)

That pattern requires that you pass in the class of what you expect to get
out.

If XXXProvider implements MessageBodyReader, then it must have a
implement the read API against the same T. You can't, legitimately, cast it
to MessageBodyReader.

So, if AegisProvider implements MessageBodyReader, 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, you then AegisProvider 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 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)
>
> type - the class of object that is to be written.
>
> So I don't think we should pass Object.class for MessageBodyWriter.
> If one would like to avoud doing casts during testing then it should be just
>  MessageBodyWriter and I'm pretty sure the runtime will pass
> Book.class.
>
> Cheers, Sergey
>
>
>
>  On Sat, Sep 5, 2009 at 1:57 PM, Benson Margulies > >wrote:
>>
>>  JAX-RS defines two fundamental interfaces: MessageBodyReader and
>>> MessageBodyWriter, 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, not MessageBodyX.
>>>
>>>
>> Allow me to modulate this claim. I thought about it some more.
>>
>> If you want to define a class as 'implements MessageBodyX', fine.
>> However, the right thing to pass to the Class 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 in a way that requires constant
>>> @SupressWarnings("unchecked") if the base is MessageBodyX.
>>>
>>> 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
>>>
>>> then implemented interface comes up as MessageBodyReader, not
>>> MessageBodyReader. 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.
>>>
>>>
>>
>


Re: JAX-RS and generics

2009-09-07 Thread Sergey Beryozkin

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)

type - the class of object that is to be written.

So I don't think we should pass Object.class for MessageBodyWriter. If one would like to avoud doing casts during testing 
then it should be just  MessageBodyWriter and I'm pretty sure the runtime will pass Book.class.


Cheers, Sergey



On Sat, Sep 5, 2009 at 1:57 PM, Benson Margulies wrote:


JAX-RS defines two fundamental interfaces: MessageBodyReader and
MessageBodyWriter, 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, not MessageBodyX.



Allow me to modulate this claim. I thought about it some more.

If you want to define a class as 'implements MessageBodyX', fine.
However, the right thing to pass to the Class 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 in a way that requires constant
@SupressWarnings("unchecked") if the base is MessageBodyX.

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

then implemented interface comes up as MessageBodyReader, not
MessageBodyReader. 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.







Re: JAX-RS and generics

2009-09-06 Thread Benson Margulies
There are two ways to look at this. From the point of view of a 'provider
bean', I can believe that a non-generic class is attractive. Maybe
essential. Maybe my change to the Aegis providers was thus a mistake.

>From the point of view of a clean API callable without suppressing any
warnings, on the other hand, the generic nature of the JAX-RS APIs makes
them ugly to reduce to non-generic types.



On Sun, Sep 6, 2009 at 6:09 PM, Sergey Beryozkin wrote:

> Hi
>
> I'm concerned it may be not be portable, that is the providers which
> work with other JAXRS implementations will end up being unusable in CXF.
>
> You may be right but I've seen the number of providers which implement
> MessageBodyX and then cast them internally. For ex to Feed or
> Entry, etc.
>
> Let me ask a question on the jaxrs users list...
> Cheers, Sergey
>
> -Original Message-
> From: Benson Margulies [mailto:bimargul...@gmail.com]
> Sent: 06 September 2009 03:15
> To: CXF Dev
> Subject: Re: JAX-RS and generics
>
> On Sat, Sep 5, 2009 at 1:57 PM, Benson Margulies
> wrote:
>
> > JAX-RS defines two fundamental interfaces: MessageBodyReader and
> > MessageBodyWriter, 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, not MessageBodyX.
> >
>
> Allow me to modulate this claim. I thought about it some more.
>
> If you want to define a class as 'implements MessageBodyX',
> fine.
> However, the right thing to pass to the Class 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 in a way that requires constant
> > @SupressWarnings("unchecked") if the base is MessageBodyX.
> >
> > 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
> >
> > then implemented interface comes up as MessageBodyReader, not
> > MessageBodyReader. 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.
> >
>


RE: JAX-RS and generics

2009-09-06 Thread Sergey Beryozkin
Hi

I'm concerned it may be not be portable, that is the providers which
work with other JAXRS implementations will end up being unusable in CXF.

You may be right but I've seen the number of providers which implement
MessageBodyX and then cast them internally. For ex to Feed or
Entry, etc.

Let me ask a question on the jaxrs users list...  
Cheers, Sergey  

-Original Message-
From: Benson Margulies [mailto:bimargul...@gmail.com] 
Sent: 06 September 2009 03:15
To: CXF Dev
Subject: Re: JAX-RS and generics

On Sat, Sep 5, 2009 at 1:57 PM, Benson Margulies
wrote:

> JAX-RS defines two fundamental interfaces: MessageBodyReader and
> MessageBodyWriter, 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, not MessageBodyX.
>

Allow me to modulate this claim. I thought about it some more.

If you want to define a class as 'implements MessageBodyX',
fine.
However, the right thing to pass to the Class 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 in a way that requires constant
> @SupressWarnings("unchecked") if the base is MessageBodyX.
>
> 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
>
> then implemented interface comes up as MessageBodyReader, not
> MessageBodyReader. 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.
>


Re: JAX-RS and generics

2009-09-05 Thread Benson Margulies
On Sat, Sep 5, 2009 at 1:57 PM, Benson Margulies wrote:

> JAX-RS defines two fundamental interfaces: MessageBodyReader and
> MessageBodyWriter, 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, not MessageBodyX.
>

Allow me to modulate this claim. I thought about it some more.

If you want to define a class as 'implements MessageBodyX', fine.
However, the right thing to pass to the Class 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 in a way that requires constant
> @SupressWarnings("unchecked") if the base is MessageBodyX.
>
> 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
>
> then implemented interface comes up as MessageBodyReader, not
> MessageBodyReader. 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.
>