Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] posting generic multiple records "List<T>" doesn't work. #607

Open
ebett opened this issue Apr 9, 2014 · 6 comments
Open

[BUG] posting generic multiple records "List<T>" doesn't work. #607

ebett opened this issue Apr 9, 2014 · 6 comments

Comments

@ebett
Copy link

ebett commented Apr 9, 2014

This problem was found in vraptor-3.5.2 and vraptor-3.5.4-SNAPSHOT.
I try with OGNL 2.7.3 and IOGI 1.0.0

I have this method in a abstract controller.

@Post
public void removeMany(List<T> records) {
        if(records!=null && records.size()>0){
            try {

                this.repository.delete(records);
                this.result.use(http()).body("{success:true}");
            } 
            catch (Exception ex) {
                fillLogicErrors("removeMany", ex);
            }
        }
}

Vraptor Exception:

GRAVE: Servlet.service() para servlet default lanzó excepción 
java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class 
at br.com.caelum.vraptor.http.ognl.ListNullHandler.instantiate(ListNullHandler.java:49) 
at br.com.caelum.vraptor.http.ognl.ReflectionBasedNullHandler.nullPropertyValue(ReflectionBasedNullHandler.java:59) 
at ognl.ASTProperty.getValueBody(ASTProperty.java:11 
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212) 
at ognl.SimpleNode.getValue(SimpleNode.java:236) 
at ognl.ASTChain.setValueBody(ASTChain.java:222) 
at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220) 
at ognl.SimpleNode.setValue(SimpleNode.java:279) 
at ognl.Ognl.setValue(Ognl.java:737) 
at ognl.Ognl.setValue(Ognl.java:783) 
at br.com.caelum.vraptor.http.ognl.OgnlFacade.setValue(OgnlFacade.java:100) 
at br.com.caelum.vraptor.http.ognl.OgnlParametersProvider.setProperty(OgnlParametersProvider.java:162) 
at br.com.caelum.vraptor.http.ognl.OgnlParametersProvider.createParameter(OgnlParametersProvider.java:134) 
at br.com.caelum.vraptor.http.ognl.OgnlParametersProvider.getParametersFor(OgnlParametersProvider.java:86) 
at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.getParametersFor(ParametersInstantiatorInterceptor.java:132)
at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:86) 
at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59) 
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) 
at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:4 
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) 
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) 
at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83) 
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) 
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) 
at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69) 
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) 
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) 
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) 
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) 
at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44) 
at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:91) 
at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:5 
at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:8 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
at ats.webp.core.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:31) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:16 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:9 
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:11 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) 
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999) 
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565) 
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309) 
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:90 
at java.lang.Thread.run(Thread.java:662) 
04/04/2014 10:33:27 org.apache.catalina.core.StandardWrapperValve invoke
This message was edited 2 times. Last update was at 06/04/2014 18:47:13

T is defined in the child class that extends BaseController for example:

UserController extends BaseController<User>

The post go to "user/removeMany", so the method is in the UserController.
I think that is possible found a way to solve this problem.

I don't want to create a converter for each domain class.

In this example, single generic type parameter works well.

@Post
    public void add(T data) {
        validateEntity(data);
        validator.onErrorUse(page()).forwardTo("/json-resp.ftl");

        try {

            this.repository.insert(data);

            this.result.use(http()).body("{success:true}");
        } 
        catch (Exception ex) {
            fillLogicErrors("add", ex);         
        }
    }   
@lucascs
Copy link
Member

lucascs commented Apr 9, 2014

Same thing for IOGI:

br.com.caelum.vraptor.http.InvalidParameterException: Exception when trying to instantiate Target(name=records, type=interface java.util.List)
    at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.handleException(VRaptorInstantiator.java:96)
    at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:88)
    at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:81)
    at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.instantiateOrAddError(IogiParametersProvider.java:80)
    at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.instantiateParameters(IogiParametersProvider.java:73)
    at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.getParametersFor(IogiParametersProvider.java:63)
    at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.getParametersFor(ParametersInstantiatorInterceptor.java:132)
    at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:86)
    at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
    at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
    at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
    at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
    at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
    at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
    at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
    at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44)
    at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:91)
    at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
    at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:88)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at ats.webp.core.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:31)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class
    at br.com.caelum.iogi.reflection.Target.findRawClassType(Target.java:37)
    at br.com.caelum.iogi.reflection.Target.getClassType(Target.java:29)
    at br.com.caelum.iogi.reflection.Target.toString(Target.java:108)
    at java.lang.String.valueOf(String.java:2826)
    at java.lang.StringBuilder.append(StringBuilder.java:115)
    at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.handleException(VRaptorInstantiator.java:96)
    at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:88)
    at br.com.caelum.iogi.collections.IndexedListInstantiator.instantiate(IndexedListInstantiator.java:34)
    at br.com.caelum.iogi.collections.ListInstantiator.instantiate(ListInstantiator.java:25)
    at br.com.caelum.iogi.collections.ListInstantiator.instantiate(ListInstantiator.java:10)
    at br.com.caelum.vraptor.http.iogi.NullDecorator.instantiate(NullDecorator.java:39)
    at br.com.caelum.iogi.MultiInstantiator.instantiate(MultiInstantiator.java:20)
    at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:86)
    ... 36 more

@ebett
Copy link
Author

ebett commented Apr 22, 2014

Some news for this problem?

@lucascs
Copy link
Member

lucascs commented Apr 23, 2014

Not yet... It's not an easy fix, because we don't have access to the class that binds T at the point its properties are being set...

So we'd have to change a lot of code to support this case, we have to think more about it... Do you want to start the fix and I'll guide you through the code?

@ebett
Copy link
Author

ebett commented Apr 24, 2014

I'll start fix when I have time.

@lucascs
Copy link
Member

lucascs commented Apr 25, 2014

You don't need permission, you can just click on the Fork button and commit
on your fork, then send a Pull Request.

On Thu, Apr 24, 2014 at 6:12 PM, Esteban A. Bett
[email protected]:

I have found a solution for OGNL in the class
"br.com.caelum.vraptor.http.ognl.ListNullHandler" method "instantiate":

Object instance =null;
if(type instanceof
sun.reflect.generics.reflectiveObjects.TypeVariableImpl){
sun.reflect.generics.reflectiveObjects.TypeVariableImpl tvi =
(sun.reflect.generics.reflectiveObjects.TypeVariableImpl)type;
Type typeToInstantiate = tvi.getBounds()[0];
instance = new
Mirror().on(typeToInstantiate).invoke().constructor().withoutArgs();
}
else{
Class typeToInstantiate = (Class) ((ParameterizedType)
type).getActualTypeArguments()[0];
instance = new
Mirror().on(typeToInstantiate).invoke().constructor().withoutArgs();
}


Reply to this email directly or view it on GitHubhttps://github.com//issues/607#issuecomment-41332912
.

@ebett
Copy link
Author

ebett commented Apr 25, 2014

Ok, thank you. The solution was an error. I'll try to find a fix to this
problem in ognl or iogi library.

2014-04-24 23:50 GMT-03:00 Lucas Cavalcanti [email protected]:

You don't need permission, you can just click on the Fork button and
commit
on your fork, then send a Pull Request.

On Thu, Apr 24, 2014 at 6:12 PM, Esteban A. Bett
[email protected]:

I have found a solution for OGNL in the class
"br.com.caelum.vraptor.http.ognl.ListNullHandler" method "instantiate":

Object instance =null;
if(type instanceof
sun.reflect.generics.reflectiveObjects.TypeVariableImpl){
sun.reflect.generics.reflectiveObjects.TypeVariableImpl tvi =
(sun.reflect.generics.reflectiveObjects.TypeVariableImpl)type;
Type typeToInstantiate = tvi.getBounds()[0];
instance = new
Mirror().on(typeToInstantiate).invoke().constructor().withoutArgs();
}
else{
Class typeToInstantiate = (Class) ((ParameterizedType)
type).getActualTypeArguments()[0];
instance = new
Mirror().on(typeToInstantiate).invoke().constructor().withoutArgs();
}


Reply to this email directly or view it on GitHub<
https://github.com/caelum/vraptor/issues/607#issuecomment-41332912>
.


Reply to this email directly or view it on GitHubhttps://github.com//issues/607#issuecomment-41354470
.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants