You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A Spring Boot application that depends on spring-boot-starter-data-pa and uses Spring Mobile will create a proxy for Spring Mobile's Device interface when it's injected into a handler method. Calling isMobile on this proxy fails as follows:
org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public abstract boolean org.springframework.mobile.device.Device.isMobile()
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:220) ~[spring-aop-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at com.sun.proxy.$Proxy64.isMobile(Unknown Source) ~[na:na]
at com.example.controllers.IndexController.getIndex(IndexController.java:17) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_60]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_60]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_60]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_60]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806) ~[spring-webmvc-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729) ~[spring-webmvc-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) ~[spring-web-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85) ~[spring-web-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.28.jar:8.0.28]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_60]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_60]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.28.jar:8.0.28]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]
The culprit is ProxyingHandlerMethodArgumentResolver which takes responsibility for any argument that's an interface. I can work around the problem by ensuring that Spring Mobile's DeviceHandlerMethodArgumentResolver appears before ProxyingHandlerMethodArgumentResolver in Spring MVC's list of argument resolvers but I'd prefer not to have to do so. Can ProxyingHandlerMethodArgumentResolver be fixed so that it either doesn't claim responsibility for anything that's an interface, or so that it returns a working proxy?
Yesterday I've stumbled upon this issue. Here's minimal example to trigger this bug
@SpringBootApplication
@Controller
public class TestApplication {
@RequestMapping(path = "/bug",method = RequestMethod.POST)
public String test(List<String> entities) {
try {
entities.size();
} catch (Exception e) {
e.printStackTrace();
}
return "i'm fine";
}
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
The code above will throw an java.lang.IllegalArgumentException: Invoked method public abstract int java.util.List.size() is no accessor method! exception, in response for curl -i -X POST -d 'a' http://localhost:8080/bug to it.
This should be fixed now. We now back off interfaces from the org.springframework and java namespace unless they're annotated with @ProjectedPayload. Prefer the latter on projection interfaces going forward as that special type inspection might be removed in 2.0 again. It was just the least invasive option for a fix that could still make it into bugfix releases
Andy Wilkinson opened DATACMNS-776 and commented
A Spring Boot application that depends on
spring-boot-starter-data-pa
and uses Spring Mobile will create a proxy for Spring Mobile'sDevice
interface when it's injected into a handler method. CallingisMobile
on this proxy fails as follows:The culprit is
ProxyingHandlerMethodArgumentResolver
which takes responsibility for any argument that's an interface. I can work around the problem by ensuring that Spring Mobile'sDeviceHandlerMethodArgumentResolver
appears beforeProxyingHandlerMethodArgumentResolver
in Spring MVC's list of argument resolvers but I'd prefer not to have to do so. CanProxyingHandlerMethodArgumentResolver
be fixed so that it either doesn't claim responsibility for anything that's an interface, or so that it returns a working proxy?Affects: 1.10.2 (Fowler SR2), 1.11 GA (Gosling)
Issue Links:
("is duplicated by")
Backported to: 1.13 GA (Ingalls), 1.12.7 (Hopper SR7), 1.11.7 (Gosling SR7)
4 votes, 8 watchers
The text was updated successfully, but these errors were encountered: