Announcement Announcement Module
Collapse
No announcement yet.
SpringAOP/JDKDynamic/CGLIB proxies Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • SpringAOP/JDKDynamic/CGLIB proxies

    Here is my problem:
    I have one Spring MVC controller
    and want to log-around/time-profile method calls from this controller. I used AOP Aspect for it.

    Code:
    @Controller
    public class TestController {
    
        @Override
        @RequestMapping(value = "/locations/{latitude}/{longitude}", method = RequestMethod.GET)
        public List<String> getLocations(@PathVariable Long latitude, @PathVariable Long longitude) {
            Logger.getLogger(getClass()).debug("params:" + longitude + "/" + latitude);
            return Arrays.asList("111", "22222", "333333");
        }
    }
    
    @Aspect
    @Component
    public class Diagnostic {
    
        @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
        public void methodInvoked(){
        }
    
        @Around("methodInvoked()")
        public Object invocation(ProceedingJoinPoint pjp) throws Throwable {
            Logger.getLogger(getClass()).debug("Entering " + pjp.getSignature().getName());
    
            final Object result = pjp.proceed();
    
            Logger.getLogger(getClass()).debug("Exiting " + pjp.getSignature().getName());
            return result;
        }
    }
    Everything works fine except that on heavyload it starts throw following exception.
    Code:
    java.lang.ClassCastException: java.util.ArrayList
    	at com.ijg.rest.impl.TestController$$EnhancerByCGLIB$$59f3ba99.getLocations(<generated>)
    	at sun.reflect.GeneratedMethodAccessor170.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:592)
    	at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:212)
    	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    	at com.laquinta.service.apikey.APIKeyFilter.doFilter(APIKeyFilter.java:43)
    	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    	at java.lang.Thread.run(Thread.java:595)
    Actually there are different ClassCastExceptions thrown for one particular method.

    I assume that there is CGLIB fault. I mean it uses some own caching mechanism so on heavyload this caching is failed.

    I decided to switch from CGLIB to JDK proxying. So i introduced interface for controller and slightly changed diagnostic

    Code:
    @Controller
    public class TestController implements IController {
    
        @Override
        @RequestMapping(value = "/locations/{latitude}/{longitude}", method = RequestMethod.GET)
        public List<String> getLocations(@PathVariable Long latitude, @PathVariable Long longitude) {
            Logger.getLogger(getClass()).debug("params:" + longitude + "/" + latitude);
            return Arrays.asList("111", "22222", "333333");
        }
    }
    
    @Aspect
    @Component
    public class Diagnostic {
    
        @Pointcut("this(com.ijg.rest.IController)")
        public void methodInvoked(){
        }
    
        @Around("methodInvoked()")
        public Object invocation(ProceedingJoinPoint pjp) throws Throwable {
            Logger.getLogger(getClass()).debug("Entering " + pjp.getSignature().getName());
            final Object result = pjp.proceed();
            Logger.getLogger(getClass()).debug("Exiting " + pjp.getSignature().getName());
            return result;
        }
    }
    Then i start getting following exception.

    Code:
    java.lang.IllegalArgumentException: object is not an instance of declaring class
    HandlerMethod details: 
    Controller [$Proxy14]
    Method [public java.util.List<java.lang.String> com.ijg.rest.impl.TestController.getLocations(java.lang.Long,java.lang.Long)]
    Resolved arguments: 
    [0] [type=java.lang.Long] [value=100]
    [1] [type=java.lang.Long] [value=200]
    
    	at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:217)
    	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    	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:987)
    	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    	at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1805)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    	at java.lang.Thread.run(Thread.java:722)
    Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:601)
    	at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
    	... 27 more

    Can anyone help me with solving one of the problems - case with CGLIB or case with JDK proxy?

  • #2
    Ok problem is solved.

    There was not 1 but 2 Aspects around the controller. As soon as i combined them into one ClassCastExceptions are gone.

    Thank you for your attention

    Comment

    Working...
    X