You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by "Dmitry Gusev (JIRA)" <ji...@apache.org> on 2017/03/10 10:51:04 UTC

[jira] [Updated] (TAP5-2576) Copying annotations from interface to proxy causing problems with type-introspecting libraries like RESTEasy

     [ https://issues.apache.org/jira/browse/TAP5-2576?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Dmitry Gusev updated TAP5-2576:
-------------------------------
    Description: 
If we contribute a tapestry service as a singleton to RESTEasy (how [Tynamo's tapestry-resteasy integration|https://github.com/tynamo/tapestry-resteasy] is doing by default) it tries to pick a class (or one of its interfaces) with {{java.ws.rs.Path}} annotation and uses it as a source for its configuration.

In Tapestry 5.3 the annotation was only attached to an interface, in Tapestry 5.4 proxy class takes precedence here as it also has the annotation.

The problem is tapestry proxy classes are missing generics information and RESTEasy can't figure out which type it should use when deserialising incoming parameters.

I.e. if you have a method {{void foo(Collection<Long> ids);}} in your interface then service proxy class will have erased version of the method, i.e.: {{void foo(Collection ids)}}.

When RESTEasy tries to deserialise incoming collection its best guess is to use {{java.lang.Integer}}, because incoming JSON will have numbers. Hence {{ids}} will be a collection of {{java.lang.Integer}} and if you try to access its elements as {{Long}} you'll get an error:
{{noformat}}
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
{{noformat}}

I couldn't find any ways how to prevent the annotation copy.

Removing the annotations during class transformation processing would also be an option, but Tapestry IoC doesn't seem to allow to register custom {{PlasticClassTransformer}} for services, which came as a surprise to me, because you have this option for Tapestry components via {{ComponentClassTransformWorker2}}.

Ideally would be nice if proxy classes somehow preserve generics information inherited from implementation/interface classes.

  was:
If we contribute a tapestry service as a singleton to RESTEasy (how [Tynamo's tapestry-resteasy integration|https://github.com/tynamo/tapestry-resteasy] is doing by default) it tries to pick a class (or one of its interfaces) with {{java.ws.rs.Path}} annotation and uses it as a source for its configuration.

In Tapestry 5.3 the annotation was only attached to an interface, in Tapestry 5.4 proxy class takes precedence here as it also has the annotation.

The problem is tapestry proxy classes are missing generics information and RESTEasy can't figure out which type it should use when deserialising incoming parameters.

I.e. if you have a method {{void foo(Collection<Long> ids);}} in your interface then service proxy class will have erased version of the method, i.e.: {{void foo(Collection ids)}}.

When RESTEasy tries to deserialise incoming collection its best guess is to use {{java.lang.Integer}}, because incoming JSON will have numbers. Hence {{ids}} will be a collection of {{java.lang.Integer}} and if you try to access its elements as {{Long}} you'll get an error:
{{noformat}}
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
{{noformat}}

I couldn't find any ways how to prevent the annotation copy.

Removing the annotations during class transformation processing would also be an option, but Tapestry IoC doesn't seem to allow to register custom {{PlasticClassTransformer}}s for services, which came as a surprise to me, because you have this option for Tapestry components via {{ComponentClassTransformWorker2}}.

Ideally would be nice if proxy classes somehow preserve generics information inherited from implementation/interface classes.


> Copying annotations from interface to proxy causing problems with type-introspecting libraries like RESTEasy
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: TAP5-2576
>                 URL: https://issues.apache.org/jira/browse/TAP5-2576
>             Project: Tapestry 5
>          Issue Type: Bug
>    Affects Versions: 5.4.1
>            Reporter: Dmitry Gusev
>
> If we contribute a tapestry service as a singleton to RESTEasy (how [Tynamo's tapestry-resteasy integration|https://github.com/tynamo/tapestry-resteasy] is doing by default) it tries to pick a class (or one of its interfaces) with {{java.ws.rs.Path}} annotation and uses it as a source for its configuration.
> In Tapestry 5.3 the annotation was only attached to an interface, in Tapestry 5.4 proxy class takes precedence here as it also has the annotation.
> The problem is tapestry proxy classes are missing generics information and RESTEasy can't figure out which type it should use when deserialising incoming parameters.
> I.e. if you have a method {{void foo(Collection<Long> ids);}} in your interface then service proxy class will have erased version of the method, i.e.: {{void foo(Collection ids)}}.
> When RESTEasy tries to deserialise incoming collection its best guess is to use {{java.lang.Integer}}, because incoming JSON will have numbers. Hence {{ids}} will be a collection of {{java.lang.Integer}} and if you try to access its elements as {{Long}} you'll get an error:
> {{noformat}}
> java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
> {{noformat}}
> I couldn't find any ways how to prevent the annotation copy.
> Removing the annotations during class transformation processing would also be an option, but Tapestry IoC doesn't seem to allow to register custom {{PlasticClassTransformer}} for services, which came as a surprise to me, because you have this option for Tapestry components via {{ComponentClassTransformWorker2}}.
> Ideally would be nice if proxy classes somehow preserve generics information inherited from implementation/interface classes.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)