Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-12453

NPE in org.springframework.core.MethodParameter.getParameterName (possible race condition)

    XMLWordPrintable

    Details

    • Last commented by a User:
      true

      Description

      I have a spring application running on google app engine and today i've encountered the following exception. Judging from the source code that NPE should never happen unless two threads access the method at the same time.

      This is the place where it happens:

      org.springframework.core.MethodParameter
      	public String getParameterName() {
      		if (this.parameterNameDiscoverer != null) {
      			String[] parameterNames = (this.method != null ?
      					this.parameterNameDiscoverer.getParameterNames(this.method) :
      					this.parameterNameDiscoverer.getParameterNames(this.constructor));
      			if (parameterNames != null) {
      				this.parameterName = parameterNames[this.parameterIndex];
      			}
      			this.parameterNameDiscoverer = null;
      		}
      		return this.parameterName;
      	}
      

      The NPE occurs on line 4, i.e. parameterNameDiscoverer==null. But as there's a prior null-check I suspect, that another thread B wins the race by setting parameterNameDiscoverer to null before thread A gets to line 4.

      java.lang.NullPointerException
      	at org.springframework.core.MethodParameter.getParameterName(MethodParameter.java:367)
      	at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.updateNamedValueInfo(AbstractNamedValueMethodArgumentResolver.java:140)
      	at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.getNamedValueInfo(AbstractNamedValueMethodArgumentResolver.java:120)
      	at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:87)
      	at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
      	at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:157)
      	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:124)
      	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
      	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
      	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
      	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
      	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
      	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
      	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
      	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
      	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
      	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
      	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
      	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      	at myfilter.doFilter(AppEngineAuthFilter.java:63)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      	at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
      	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
      	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
      	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
      	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
      	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
      	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
      	at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
      	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
      	at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
      	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
      	at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
      	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
      	at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
      	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
      	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
      	at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
      	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
      	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
      	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
      	at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:254)
      	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
      	at org.mortbay.jetty.Server.handle(Server.java:326)
      	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
      	at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
      	at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
      	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
      	at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
      	at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:480)
      	at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:438)
      	at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:445)
      	at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:220)
      	at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:309)
      	at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:301)
      	at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:442)
      	at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
      	at java.lang.Thread.run(Thread.java:724)
      

      Edit: The controller method which caused that exception:

      @RequestMapping(value = "channel", method = RequestMethod.POST, consumes = "application/x-www-form-urlencoded")
      @ResponseStatus(value = HttpStatus.NO_CONTENT)
      public void handle(@RequestParam String arg1, @RequestParam String arg2, @RequestParam String arg3) {
              .... the body obviously doesn't get called, the request fails while processing the @RequestParams
      }
      

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              juergen.hoeller Juergen Hoeller
              Reporter:
              mcescher Ă–mer Yildiz
              Last updater:
              Spring Issues Spring Issues
              Votes:
              1 Vote for this issue
              Watchers:
              4 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:
                Days since last comment:
                3 years, 37 weeks, 6 days ago