users@jersey.java.net

Re: [Jersey] issue with generics in interface method parameter, POST and PUT methods

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 18 Dec 2009 13:48:20 +0100

On Dec 17, 2009, at 2:21 PM, Jarmo Torvinen wrote:

> Hi,
>
> Thanks for the prompt reply.
>
> Reported as issue 447 on the tracker.
>

This is fixed in the trunk. There are likely to be some edge cases
where this might not work that are harder to resolve, specifically
where one needs to compare compatibility of parameterized types e.g.
that Map<V, Set<T>> is compatible with Map<String, Set<Integer>>.

Paul.


> Best regards,
> Jarmo Torvinen
>
>
> 2009/12/17 Paul Sandoz <Paul.Sandoz_at_sun.com>:
>> Hi Jarmo,
>>
>> Currently you will need to move the annotations to the implementing
>> class,
>> or modify the generic interfaces to be classes that implement the
>> generic
>> methods.
>>
>> This issue is little tricky to fix, but on investigation i think i
>> can fix
>> it. Can you log an issue?
>>
>> To find the inherited method one needs to search through all the
>> methods on
>> the super class or interface for those methods with the same method
>> name and
>> same number of parameters as the inheriting method then compare
>> generic
>> parameter types of the inheriting and inherited methods.
>> Unfortunately the
>> JDK comes with very little help reflection wise for generics. :-(
>>
>> Paul.
>>
>> On Dec 17, 2009, at 11:53 AM, Jarmo Torvinen wrote:
>>
>>> Hi,
>>>
>>> I have:
>>>
>>> @MappedSuperclass
>>> @XmlRootElement
>>> @XmlAccessorType(XmlAccessType.FIELD)
>>> public abstract class AbstractObject implements Serializable {
>>> ...
>>> }
>>>
>>> @XmlRootElement(name = "Car")
>>> @XmlAccessorType(XmlAccessType.FIELD)
>>> public class Car extends AbstractObject {
>>> ...
>>> }
>>>
>>> public interface CrudRestService<T extends AbstractObject> {
>>>
>>> @POST
>>> @Produces(MediaType.APPLICATION_JSON)
>>> @Consumes(MediaType.APPLICATION_JSON)
>>> public T create(T newObject);
>>>
>>> @GET
>>> @Path("{id}")
>>> @Produces(MediaType.APPLICATION_JSON)
>>> @Consumes(MediaType.APPLICATION_JSON)
>>> public T read(@PathParam("id") long id);
>>>
>>> ...(same for update and delete)
>>>
>>> }
>>>
>>> public interface CarService extends CrudRestService<Car> {
>>>
>>> }
>>>
>>>
>>> @Path("/cars")
>>> public class CarWebService implements CarService {
>>>
>>> public Car create(Car newObject) {
>>>
>>> return new Car(newObject);
>>>
>>> }
>>>
>>> public Car read(long id) {
>>>
>>> return findCarById(id);
>>> }
>>>
>>>
>>> }
>>>
>>> Now, what is happening in real life: the read() function with
>>> GET-method works, but the create() method with POST is not working,
>>> instead, a 405 not allowed is returned.
>>>
>>> I traced the issue to AnnotatedMethod.findAnnotatedMethod() call:
>>>
>>> try {
>>> m = c.getMethod(m.getName(), m.getParameterTypes());
>>> } catch (NoSuchMethodException ex) {
>>> return null;
>>> }
>>>
>>> When this is called on a interface that uses generics, the function
>>> parameters are not matched and so the annotated method is not
>>> discovered. Are there any options to get this fixed or do I just
>>> need
>>> to move the annotations to the implementation class?
>>>
>>>
>>>
>>> --
>>> Jarmo
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>
>
>
> --
> --
> Jarmo
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>