users@jersey.java.net

Re: [Jersey] Re: Type argument in MessageBodyWriter methods

From: Marc Hadley <marc.hadley_at_oracle.com>
Date: Wed, 14 Apr 2010 17:38:36 -0400

On Apr 14, 2010, at 4:37 PM, ljnelson wrote:

> On Wed, Apr 14, 2010 at 4:31 PM, Marc Hadley-2 [via Jersey]
> <[hidden email]> wrote:
> > The isWritable method is responsible for filtering the types that the
> > writeTo will be called for so you might get a subclass of T if you decide to
> > support that.
>
> OK. Looks like I should be using a wildcard in here as you suggest.
>
> >> This leads to my next question. The first thing I need to do in my
> >> "chaining" MessageBodyWriter is to ask Providers for another one that
> >> matches. I'm armed at this point with a T, and a Class<?>. But
> >> Providers#getMessageBodyWriter() needs a Class argument that has as
> >> its parameter T. It would seem that I can't guarantee this. What's
> >> your advice?
> >>
> > If you use Class<?> then you'll get a MessageBodyWriter<?> which should
> > still work fine for you. I'd probably go that way for a chaining writer that
> > supports multiple types.
>
> OK...well, here, here's how I've implemented my getSize() method,
> which is the actual one still causing problems once I fixed the other
> wildcard issues (in the other methods):
>
> @Override
> public long getSize(final T t, final Class<?> type, final Type
> genericType, final Annotation[] annotations, final MediaType
> mediaType) {
> final MessageBodyWriter<?> delegate =
> this.providers.getMessageBodyWriter(type, genericType, annotations,
> mediaType);

Generics can be mind boggling. I don't know the correct incantation to fix this but if you change the above line to

final MessageBodyWriter delegate = ...

Then the compiler is happy.

Marc.

> if (delegate != null) {
> return delegate.getSize(t, type, genericType, annotations, mediaType);
> }
> return -1L;
> }
>
> At the moment of course this is a somewhat useless implementation,
> since I still need to do some more logic to compute the overall size.
> Let's ignore that for a moment and focus solely on the
> delegate.getSize() call. As you can see, the delegate is a
> MessageWriter<?>, which it has to be, because the incoming type
> argument is a Class<?>, and that is what I have to pass to
> Providers#getMessageBodyWriter(). When I do this--as I'm forced to
> do--in other words, I have no choice but to get back a generic
> MessageBodyWriter<?>. Now, however, I want to call this delegate's
> getSize() method, but the very first thing it needs is a ?, which is
> syntactically impossible.
>
> That is, the delegate writer can't take a T. It is, after all, not a
> MessageWriter<T>, but a MessageWriter<?>.
>
> If this is possible at all, it should follow that either there's an
> implicit guarantee in all this--perhaps that type is not actually a
> Class<?> but a Class<? extends T> or a Class<T>--or the signature of
> Providers#getMessageBodyWriter() is too strict.
>
> Thanks for your help here.
>
> Best,
> Laird
>
> View this message in context: Re: Type argument in MessageBodyWriter methods
> Sent from the Jersey mailing list archive at Nabble.com.